using std::shared_ptr with a protected constructor\destructor [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I call ::std::make_shared on a class with only protected or private constructors?
I want to create a shared pointer to a class, and have a factory method that returns it while keeping the constructor\destructor protected. since the shared pointer can't access the the constructor or the destructor, I get compiler errors.
I am using llvm 4.1, but I am looking for a solution that can be compiler independent (besides making the constructor\destructor public).
this is a code sample:
class Foo
{
public:
static std::shared_ptr<Foo> getSharedPointer()
{
return std::make_shared<Foo>();
}
protected:
Foo(int x){}
~Foo(){}
};
any Ideas?

Just allocate the pointer yourself instead of calling make_shared:
static std::shared_ptr<Foo> getSharedPointer()
{
return std::shared_ptr<Foo>(new Foo);
}
Note, however, that this would require making the destructor public.

Related

C++ Call child function from parent [duplicate]

This question already has answers here:
call to pure virtual function from base class constructor
(8 answers)
Calling virtual functions inside constructors
(15 answers)
Closed 1 year ago.
I am trying to call an overriden function from the parent, and found out that it just crashes.
This is quite hard to describe, so here the minimal reproducible code:
#include <iostream>
class A
{
public:
A()
{
init1();
}
void init1()
{
printf("1");
init2();
printf("2");
}
virtual void init2() = 0;
};
class B : public A
{
public:
B()
: A()
{}
void init2() override
{
printf("hello");
}
};
int main()
{
B b;
return 0;
}
On MSVC 2019 it crashes, on http://cpp.sh/ it outputs "1" and then main() returns 0, but we never see "hello" or "2".
Why does it crash? What happens from a low level point of view? Is A trying to call its own init2()?
Is there a way of doing it, so I don't have to, in every derived class, add init2() in its constructor?
You can't call a derived class's overriden methods from within a base class constructor (or destructor). The derived class portion of the object doesn't exist yet.
So, to answer your questions:
yes A::A() is trying to call A::init2(), not B::init2(), and thus crashes from calling a pure virtual method.
There are ways (like via CRTP) for a base class constructor to call a derived class method, but doing so has limitations to it (ie, not being able to access any derived class data members since they still don't exist yet, only base class data members can be accessed). In your example, B::init2() doesn't access anyB data members, so it is possible for A::A() to call B::init2(), but in general you really need to wait for B to begin/finish constructing itself before you can safely call B::init2().

Making class constructor private [duplicate]

This question already has answers here:
C++11 "auto" semantics
(3 answers)
Closed 6 years ago.
I am writing a simple garbage collector in C++. I need a singleton class GarbageCollector to deal with different types of memory.
I used a Meyer's singleton pattern. But when I try to call instance, an error appears:
error: ‘GarbageCollector::GarbageCollector(const GarbageCollector&)’ is private
GarbageCollector(const GarbageCollector&);
^
Here is the class definition.
class GarbageCollector //Meyers singleton (http://cpp-reference.ru/patterns/creational-patterns/singleton/)
{
public:
static GarbageCollector& instance(){
static GarbageCollector gc;
return gc;
}
size_t allocated_heap_memory;
size_t max_heap_memory;
private:
//Copying, = and new are not available to be used by user.
GarbageCollector(){};
GarbageCollector(const GarbageCollector&);
GarbageCollector& operator=(GarbageCollector&);
};
I call the instance with the following line:
auto gc = GarbageCollector::instance();
Change
auto gc = GarbageCollector::instance();
to
auto& gc = GarbageCollector::instance();
Otherwise gc is not a reference, then returned GarbageCollector need to be copied, but the copy ctor is private, that's why compiler complains.

Private implementation for public interface method [duplicate]

This question already has answers here:
Overriding public virtual functions with private functions in C++
(7 answers)
Closed 7 years ago.
I have encountered a piece of code with method being exposed via public interface while the implementation is private. I'm not sure what should be the expected behavior. Simplified example:
#include <iostream>
class Interface
{
public:
virtual ~Interface() {}
virtual void myIfMethod() = 0;
};
class Derived : public Interface
{
private:
void myIfMethod(){std::cout << "private method invoked via public interface" << std::endl;}
};
int main()
{
Interface* myObj = new Derived;
myObj->myIfMethod();
delete myObj;
return 0;
}
This sample compiles and executes without a warning: http://ideone.com/1Ouwk4
Is this a correct and well-defined behavior? And if so, why?
Note, the question isn't about private interface method with public implementation (there are multiple such questions on SO) but the other way around.
C++ standard draft
Access to virtual functions [class.access.virt]
1 The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it.
2 Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
The function is called through a pointer of type Interface in which the member function is public, so the access is allowed. The access of the derived member function is not known and has no effect. The behaviour is correct and well defined as far as the standard is concerned.
Of course, it might be quite pointless to define the overriding function private since it's accessible through virtual dispatch anyway.

Difference in constructors with X() = delete; and private X(); [duplicate]

This question already has answers here:
Which is the difference between declaring a constructor private and =delete?
(7 answers)
Closed 7 years ago.
Let us assume we have a class X and we want wo explicitly forbid, let say the standard constructor. I used for a long time in the Header file:
private:
X(); // 1.
so, that the contructor was disabled outside the class, so for anybody. But recently I have learned that in C++11 follwoing was recommended:
X() = delete; // 2.
Both would achive my wish to forbid the standard contructor.
But what is the exact difference bewteen them? Why would C++11 recommend the last one? Are there any other flags, signals set in the 2. way?
Example 1 was the way to do it before we had = delete which came out in C++11. Now that we have = delete this will completely get rid of the constructor. With making the constructor private you could still use that constructor in a member function where if you try to default an object in a member function with = delete it will be a compiler error.
#include <iostream>
class Foo
{
Foo();
public:
static void SomeFunc() { Foo f; }
};
class Bar
{
public:
Bar() = delete;
static void SomeFunc() { Bar b; }
};
int main()
{
Foo::SomeFunc(); // will compile
Bar::SomeFunc(); // compiler error
}
Live Example
The former is kind of a hack. A friend class could still call the constructor (and you'd get an error at link-time unless you actually defined it as well).
The latter actually prevents its auto-generation so it's really not there.

Smart unique pointer as a member variable [duplicate]

This question already has an answer here:
How to initialize a shared_ptr that is a member of a class?
(1 answer)
Closed 8 years ago.
I have a class as:
class LargeObject
{
public:
LargeObject();
void DoSomething();
private:
std::unique_ptr<Thing> pThing;
};
Then when I want to create the pointer in the constructor
LargeObject()
{
pThing(new Thing()); //This does not work.
}
I want to use the member variable throughout the code. How to do that?
I think initialization should be in constructor's initialization list, that's the place where constructors should be invoked from another constructor:
LargeObject()
:pThing(new Thing){}