Как мне получить доступ к приватному конструктору в отдельном классе?

Я пишу библиотеку на C ++. У меня есть два класса в моей библиотеке, A а также B, Я хочу спрятать A() конструктор из любого кода, который ссылается на мою библиотеку. Я тоже хочу класс B чтобы иметь возможность позвонить A() конструктор.

Я родом из C # и мало помню свой C ++. В C # я бы просто объявил A() конструктор как internal, Я читал, что самый близкий способ сделать это в C ++ это сочетание friend декларации и форвард-декларации. Как мне это сделать? Вот мои три файла ниже:

хиджры:

#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();

Я вместо этого попытался добавить и extern class B; в A.h и превращение B в такой класс:

public: friend class B;

Я в недоумении.

Я думаю, что это может быть проще, если у меня есть B::createA() функция возвращает указатель на A объект, а не A возражать напрямую, но в моем случае это не сработает. Я эмулирую закрытый API, и вызов API возвращает A объект, а не указатель.

7

Решение

Вам, вероятно, просто нужно отбросить «extern» с третьей попытки, чтобы превратить его в правильное предварительное объявление. Пытаться:

хиджры:

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

Другие решения

Вам не нужно 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() {}
};

Живой пример.

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;
}
1

Вы можете сделать B другом A:

class A
{
private:
A();
friend class B;
};
0
По вопросам рекламы [email protected]