I'm writing a library in C++. I have two classes in my library, A
and B
. I want to hide the A()
constructor from any code that references my library. I also want class B
to be able to call the A()
constructor.
I come from a C# background and remember little of my C++. In C#, I would simply declare the A()
constructor as internal
. I've read that the closest way to do this in C++ is a combination of friend
declarations and forward-declarations. How do I do this? Here are my three files below:
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;
}
I've tried adding this to A.h:
public: friend A createA();
I've instead tried adding this to A.h with a corresponding forward declaration:
public: friend A B::createA();
I've instead tried adding and extern class B;
to A.h and making B a class like this:
public: friend class B;
I'm at a loss.
I think this might be easier if I have the B::createA()
function return a pointer to an A
object rather than an A
object directly, but that won't do in my case. I am emulating a closed API and the API call returns an A
object rather than a pointer.
A private constructor does not allow to create an object outside the class.
We can declare a constructor private by using the private access specifier. Note that if a constructor is declared private, we are not able to create an object of the class. Instead, we can use this private constructor in Singleton Design Pattern.
Private constructors are used to prevent creating instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the complete class static.
Yes, we can access the private constructor or instantiate a class with private constructor.
You probably just need to drop the "extern" from your third attempt to turn it into a proper forward-declaration. Try:
A.h:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
You don't need the external
keyword. Make it simple:
// 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With