C++友元函数和私有(private)构造函数

标签 c++ oop

#include <iostream>
using namespace std;

class A;

class B {
public:
    A createA();
};

class A {
private:
  A() {
      cout << "A Object created" << endl;
  }

  friend A B::createA();
};

A B::createA() {
    A a_obj;
    return a_obj;
}

int main(int argc, char* argv[]) {
    B b;
    A a = b.createA();
}

上面的代码可以正常工作!

但我有以下问题:-

  1. 我尝试交换 class Aclass B 的位置,但它产生了一个错误,指出 A::A() 不可访问并尝试访问不完整类型 B 类 为什么?
  2. 任何人都可以帮助我理解当您编写 friend A B::createA(); 时发生了什么,它是否试图立即访问 createA() 的定义。

最佳答案

这个有问题的部分是 B::createA

在这里,您正在“接触”类型 B 以提取其成员函数 createA。为此,您需要知道完整的类型 B。否则,编译器如何知道在哪里可以找到该成员函数,或者它是否存在?

为了声明友元成员函数,从编译器实现的严格技术角度来看,这不是必需的。毕竟,此时您没有进行任何函数调用,所以这里没有什么要解决的。但这仍然会有问题,因为我也可以改为编写 B::thisfunctiondoesnotexist,编译器也必须接受它。因此,无论何时您使用 :: 提取它的一些内部结构,该语言都选择要求事先知道完整类型。

解决此限制的一个简单方法(例如,如果您需要避免类之间的循环依赖)是将 createA 的功能放入自由函数而不是成员函数中。如果类型仅在此时前向声明但未定义,则仍然可以声明依赖于 AB 的自由函数。

关于C++友元函数和私有(private)构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62464656/

相关文章:

php - 使用两种语言时如何决定是使用 JavaScript 还是 PHP 对象?

java - 对象 o = makeMeAnObjectPlease(); 之间的区别和 Object o = new Object();

javascript - js : method can't access property

c++ - std::vector::swap 是如何实现的?

c++ - 一个类可以继承自另一个具体化的类模板吗?

c++ - 在 C++ 中包含两次头文件

oop - 为什么要在构造函数中初始化成员变量?

c++ - 输出随机数

c++ - 没有 getline 的重载函数实例

php - 当不在对象上下文中而不使用静态方法时使用 $this