【问题标题】:Why is this private constructor inaccessible to its friend为什么它的朋友无法访问这个私有构造函数
【发布时间】:2013-06-30 05:04:13
【问题描述】:
#include <iostream>

using namespace std;


class B {
private:
  class A;
  friend void f ( A Aobj );
  B ( int i ) {}
};

class A{
};


void f ( A Aobj ) {
  B Bobj ( 1 );
}

int main() {      
}

g++ 产生以下错误:

$ g++ a.cpp
a.cpp: In function ‘void f(A)’:
a.cpp:10: error: ‘B::B(int)’ is private
a.cpp:18: error: within this context

如果进行以下任何更改,错误就会消失: 1.从B的构造函数中去掉“int i”。 2. 将 f 的数据类型从 A 更改为其他任何类型:例如 void f ( int Aobj )。 3、在B之前定义A类,去掉A的前向声明。

【问题讨论】:

    标签: c++ constructor g++ private friend


    【解决方案1】:

    您已将 B 的构造函数 - 函数 B (int i){} 声明为私有方法。你想公开它,像这样:

    class B {
    private:
      class A;
      friend void f ( A Aobj );
    public:
      B ( int i ) {}
    };
    

    **已编辑

    如果你想让构造函数保持私有,那应该不是问题。再看一遍,我意识到错误在于类 A 的前向声明。您在 B 的类定义中声明了 A,然后尝试在 f 的函数头中使用它。问题是您还没有完全定义 A,因此您还不能引用该对象 - 编译器不知道 A 占用了多少内存,因此无法定义该函数。要解决此问题,您要么需要在对 A 的任何引用之前完全定义类 A,要么切换 f 以获取指向 A 的指针(即void f (A* Aobj))。指针是固定大小的,因此即使 A 尚未完全定义,也可以使用它们。

    【讨论】:

    • f 是 B 的朋友,所以 f 应该也可以访问 B 的私有方法。
    • 另外请注意,在原始代码中,如果B的构造函数的参数(“int i”)被删除,它可以正常编译。
    • 我认为我已经编辑了更好的答案。我很确定当你删除参数时会发生什么是编译器假定你正在使用隐式构造函数,它是公共的。
    • @rkevingibson 我不这么认为。当您显式定义私有构造函数时,编译器无法将其覆盖为公共构造函数。或者可以吗?我必须深入研究标准...
    【解决方案2】:

    问题是友元函数采用B::A,而文件后面的函数采用A。将class A 的前向声明移出B

    【讨论】:

    • +1,同上。您的 f() 声明与您在 B() 声明中作为朋友提到的 f() 是不同的函数。
    • 是的,这是有道理的。谢谢你:)
    • 好的,但是你现在能解释一下当你从构造函数中删除int参数时观察到的编译结果吗?为什么会在这种情况下编译?
    • @ondav:也许这和Most Vexing Parse有关?
    猜你喜欢
    • 2022-07-22
    • 2014-07-31
    • 1970-01-01
    • 2021-08-16
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多