【问题标题】:Is there a function that help using a private struct是否有帮助使用私有结构的功能
【发布时间】:2019-04-11 13:20:21
【问题描述】:

我需要一个可以进入私有结构的函数

    #include <iostream>
    using namespace std;

    struct abc {
    private:
        int a;
    }b;

    int main(){
        //i want to use the variable a
        system("pause");
    }

【问题讨论】:

  • 如果你想访问它,它的私密性有什么意义?!
  • 我同意,这有什么意义。但是,如果您想访问a 变量,那么唯一的方法是使用abc 的方法或使用声明为abc 的朋友的函数。如果你解释为什么你想这样做,你会得到一个更好的答案。
  • struct a { int a; } 然后((a*)&amp;b)-&gt;a = 42 应该这样做。
  • @DeiDei 这将是未定义的行为 - 将对象转换为它们不是的东西可能看起来很有效,但即使它们具有相同的成员,编译器也可能对它们进行了不同的优化。最好有struct a{int a;}; struct abc: private a{};(也 - 答案在下面,以便人们可以否决他们)
  • 你可以访问abc定义吗?

标签: c++ struct private


【解决方案1】:

这会破坏封装。

如果你需要读取变量a,你可以创建一个getter:

struct abc {
int getA() const;
private:
    int a;
};

如果你需要修改变量,你应该创建一个setter:

struct abc {
void setA(int);
private:
    int a;
};

有一种方法可以使用friend function,但我不建议你这样做。

如果是struct,如果您需要访问权限且无需封装,请考虑将a 公开。

【讨论】:

    【解决方案2】:

    如果您想允许特定的类/结构或函数访问私有成员,请使用friend 声明。这通常仅用于密切相关的事物,以免成员可以访问其他地方的所有事物(在其他语言中,internal 之类的事物类似)。

    struct abc {
    private:
        int a;
        friend int main();
    };
    
    void foo(abc &x) {
        x.a = 5; // ERROR
    }
    int main(){
        abc x;
        x.a = 2; // OK
        foo(x);
        //i want to use the variable a
        system("pause");
    }
    

    如果您想要只读访问,通常会使用“getter”,例如

    struct abc {
        int get_a()const { return a; }
    private:
        int a = 45;
    };
    
    int main() {
        abc x;
        std::cout << x.get_a(); // OK
    }
    

    对于读写,还有一个 get 和 set 函数。 set 函数可能会进行额外的验证或其他逻辑。

    struct abc {
        int get_a()const { return a; }
        void set_a(int x)
        {
            if (x % 2) throw std::invalid_argument("abc must be even");
            a = x;
        }
    private:
        int a = 45;
    };
    
    int main() {
        abc x;
        x.set_a(50);
        std::cout << x.get_a();
        x.set_a(51); // throws
    }
    

    【讨论】:

      【解决方案3】:

      除了声明它们的类之外,任何人都不应访问私有字段和方法。但是,在某些情况下需要它。例如,如果您想序列化/打印您的结构。对于这些情况,您可以使用 friend 关键字声明一个函数或另一个类。比如:

      struct abc
      {
      private:
          friend std::ostream &operator<<(std::ostream &stream, const abc &s);
      
          int a;
      };
      

      然后您将在某处实现具有相同签名std::ostream &amp;operator&lt;&lt;(std::ostream &amp;stream, const abc &amp;s); 的函数,并且它可以访问abc::a

      std::ostream &operator<<(std::ostream &stream, const abc &s)
      {
          return stream << s.a;
      }
      

      这将允许使用您的结构,例如 std::cout

      请注意,像这样的真实案例并不多,您应该尽可能避免使用friend。例如,在这种情况下,getter 方法会做同样的事情,您可以在不破坏封装的情况下避免整个问题。

      【讨论】:

      • @Aconcagua 是的。 :-) 已编辑。
      猜你喜欢
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多