Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to call a private constructor from a static method defined in the cpp?

Tags:

c++

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();
}
like image 869
ansiart Avatar asked Jun 22 '12 18:06

ansiart


People also ask

Can static method call private constructor?

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.

Can static method access private constructor C++?

Yes, the static function has access.

Can you call a private constructor in C++?

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.

Can we access private non static characteristics of class from static method C++?

Yes, private non static variable/methods are accessible by a static function that is part of the self-same class.


2 Answers

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.

like image 89
Albert Avatar answered Oct 12 '22 08:10

Albert


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();
}
like image 28
BЈовић Avatar answered Oct 12 '22 07:10

BЈовић