如何在单独的类中访问私有构造函数?

时间:2013-09-09 18:31:35

标签: c++ friend internal forward-declaration

我正在用C ++编写一个库。我的库中有两个类,AB。我想隐藏任何引用我的库的代码中的A()构造函数。我还希望课程B能够调用A()构造函数。

我来自C#背景,并且很少记住我的C ++。在C#中,我只是将A()构造函数声明为internal。我已经读过,在C ++中最接近的方法是friend声明和前向声明的组合。我该怎么做呢?以下是我的三个文件:

A.H:

#pragma once
class A
{
    private:
        A();
};

B.h

#pragma once
class A;
class B
{
    public:
        A createA();
};

B.cpp:

#include "A.h"
#include "B.h"

A B::createA()
{
    A result; //cannot access private member declare in class 'A'
    return result;
}

我已经尝试将其添加到A.h:

public: friend A createA();

我试图将此添加到A.h,并附带相应的前瞻声明:

public: friend A B::createA();

我反而尝试向A.h添加extern class B;并使B成为这样的类:

public: friend class B;

我很茫然。

我认为如果我让B::createA()函数直接返回指向A对象而不是A对象的指针,这可能会更容易,但在我的情况下不会这样做。我正在模拟一个封闭的API,API调用返回一个A对象而不是一个指针。

4 个答案:

答案 0 :(得分:3)

您可能只需要从第三次尝试中删除“extern”,将其转换为正确的前向声明。尝试:

A.H:

#pragma once
class B;
class A
{
    friend class B;
private:
    A();
};

答案 1 :(得分:1)

除非绝对必要,否则您应该A构建自己(或者拥有一个创建A的工厂)。如果您真的希望B这样做:

class B; // foward declared

class A
{
private:
    A() {}
    friend class B;
};

class B
{
public:
    A CreateA()
    {
        A a;
        return a;
    }
};

int main()
{
    B b;
    A a = b.CreateA();
    return 0;
}

注意:在B中声明为friend之前,您必须转发声明A

如果您只想将此功能作为朋友:

class A;

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

class A
{
private:
    A() {}
    friend class A B::CreateA();
};

A B::CreateA()
{
    A a;
    return a;
}

int main()
{
    B b;
    A a = b.CreateA();
    return 0;
}

答案 2 :(得分:1)

您不需要external关键字。简单说明:

// In A.h

class B;  // Forward declaration

class A
{
    friend class B; // Make all the class B friend
    A();
};

// In B.h

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

Live Example

答案 3 :(得分:0)

你可以让B成为A的朋友:

class A
{
private:
   A();
   friend class B;
};