Я пишу библиотеку на 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
объект, а не указатель.
Вам, вероятно, просто нужно отбросить «extern» с третьей попытки, чтобы превратить его в правильное предварительное объявление. Пытаться:
хиджры:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
Вам не нужно 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() {}
};
Если это абсолютно необходимо, вы должны иметь 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;
}
Вы можете сделать B другом A:
class A
{
private:
A();
friend class B;
};