A C++ n00b question. Is it possible to call a private constructor from a static method defined in the cpp? I'd like to keep methods out of the header file if possible -- I figure there should be a way to do this. I'm getting an error when attempting this:
"cannot access private member declared in class SomeClass"
/////////////////
// SomeClass.h //
/////////////////
class SomeClass {
public:
static SomeClass SomeMethod();
private:
SomeClass(int i);
}
///////////////////
// SomeClass.cpp //
///////////////////
static SomeClass OSImplementation() {
return SomeClass(0);
};
// calls implementation
SomeClass SomeClass::SomeMethod() {
return OSImplementation();
}
It has already blown my mind that one class instance can access the private variables of another class instance. So, I started to wonder if Static methods were granted the same kind of access. And, if so, could they be used to invoke private constructors on their own class. Spoiler alert: they are and they can.
Yes, the static function has access.
A private copy constructor can only be invoked by members and friends of the class. One common pattern I have seen and used is to make all constructors private, and instead provide either a factory function that's a friend, or a static factory method that can create new instances.
Yes, private non static variable/methods are accessible by a static function that is part of the self-same class.
You can make OSImplementation
a friend method.
Or you can make OSImplementation
a static method within the class (but that has to be declared in the header).
Or, probably the most common way to do this, is to have an internal implementation class, like this:
class SomeClass {
public:
//...
private:
struct Impl;
Impl* intern;
};
In your cpp file, you declare struct SomeClass::Impl
.
In your constructor, create the SomeClass::Impl
instance. Delete it in the destructor. And implement the copy-constructor and the assignment operator!
This is called the PIMPL (pointer to implementation) idiom (Wikipedia, c2.com). It's used a lot in big projects like Qt.
Yes, it is possible, by making the OSImplementation()
friend of SomeClass. Next example compiles without warnings and errors using g++ 4.6.1 :
#include <iostream>
// declare in hpp
class SomeClass {
friend SomeClass OSImplementation();
public:
static SomeClass SomeMethod();
void foo();
private:
SomeClass(int);
};
int main()
{
auto obj = SomeClass::SomeMethod();
obj.foo();
}
// define in cpp
SomeClass SomeClass::SomeMethod(){
return SomeClass( 5 );
}
SomeClass::SomeClass(int){
}
void SomeClass::foo(){
std::cout<<"foo"<<std::endl;
}
SomeClass OSImplementation()
{
return SomeClass::SomeMethod();
}
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