Custom reference counting pointer calls destructor right after creation - c++

I am currently reading the "3D Game Engine Architecture" book by David H. Eberly, and decided to implement my own little reference counting smart pointer. I have mostly followed his implementation, but I am experiencing a problem with my implementation.
I created a function called 'CreateRef' which returns a Pointer. All is well when I use this function in the same scope as the object I have created, but the moment I put the object in the global scope it destroys the object right after creation.
class Object
{
public:
void IncrementReferences()
{
++m_References;
}
void DecrementReferences()
{
if(--m_References == 0) delete this;
}
int GetReferenceCount() const { return m_References; }
private:
int m_References = 0;
};
template<class T>
class Pointer
{
public:
//costr and destr
Pointer(T* pObject = nullptr)
{
m_pObject = pObject;
if (m_pObject)
m_pObject->IncrementReferences();
}
Pointer(const Pointer& rPointer)
{
m_pObject = rPointer.m_pObject;
if (m_pObject)
m_pObject->IncrementReferences();
}
~Pointer()
{
if (m_pObject)
m_pObject->DecrementReferences();
}
// implicit conversions
operator T* () const
{
return m_pObject;
}
T& operator* () const
{
return *m_pObject;
}
T* operator-> () const
{
return m_pObject;
}
// Assignment
Pointer& operator= (T* pObject)
{
if (m_pObject != pObject)
{
if (pObject)
pObject->IncrementReferences();
if (m_pObject)
m_pObject->DecrementReferences();
m_pObject = pObject;
}
return *this;
}
Pointer& operator= (const T* rReference)
{
if (m_pObject != rReference)
{
if (rReference)
rReference->IncrementReferences();
if (m_pObject)
m_pObject->DecrementReferences();
m_pObject = rReference;
}
return *this;
}
// Comparisons
bool operator== (T* pObject) const { return m_pObject == pObject; }
bool operator!= (T* pObject) const { return m_pObject != pObject; }
bool operator== (const Pointer& rReference) const { return m_pObject == rReference.m_pObject; }
bool operator!= (const Pointer& rReference) const { return m_pObject != rReference.m_pObject; }
protected:
// The shared object
T* m_pObject;
};
template<typename T>
using Ref = Pointer<T>;
template<typename T, typename ...Args>
constexpr Ref<T> CreateRef(Args&&... args)
{
return Ref<T>(new T(args...));
}
Main
static Ref<Person> person = nullptr; // Doesn't work like this
static void DoSomething()
{
person = CreateRef<Person>("Name");
std::cout << "References " << person->GetReferenceCount() << std::endl;
Ref<Person> newPerson = person;
std::cout << "References " << newPerson->GetReferenceCount() << std::endl;
}
int main()
{
DoSomething();
std::cout << person->GetReferenceCount();
}
I have a feeling I am doing something wrong with the 'Pointer' class but I can't quite understand what I am missing.

Thanks for the help. I found two solutions to my problem.
First solution is to add a copy assignment operator to the Pointer class.
Pointer& operator= (Pointer& rPointer)
{
if (m_pObject != rPointer.m_pObject)
{
if (rPointer)
rPointer.m_pObject->IncrementReferences();
if (m_pObject)
m_pObject->DecrementReferences();
m_pObject = rPointer.m_pObject;
}
return *this;
}
Another solution (albeit not what I was looking for) was to change the return type of the CreateRef() function to be a T*
template<typename T, typename ...Args>
constexpr T* CreateRef(Args&&... args)
{
return new T(args...);
}

Related

C++ Anyone know more about this kind of pointer?

I have a World class and a Entity class.
The World class creates new Entites and retuns a pointer to it.
If i use that pointer im never sure if that pointer is still pointing to a valid Entity but i also dont want to use a shared_ptr because the Entity wont get deleted until all shared_ptr are released. So after some time i cameup with this pointer:
#include <iostream>
#include <unordered_map>
template<class T>
class Pointer
{
public:
Pointer() :m_ptr(nullptr){}
Pointer(T*p) :m_ptr(p) { m_ptr->addPtr(this); }
~Pointer() { if(valid()) m_ptr->removePtr(this); }
Pointer(const Pointer &other) :m_ptr(other.m_ptr)
{
if(valid())
m_ptr->addPtr(this);
}
Pointer& operator=(const Pointer& other)
{
if (valid())
m_ptr->removePtr(this);
m_ptr = other.m_pObj;
if (valid())
m_ptr->addPtr(this);
return *this;
}
T* operator->() { return m_ptr; }
T* operator*() { return *m_ptr; }
T* get() { return m_ptr; }
bool valid() { return m_ptr != nullptr; }
private:
template<typename T>
friend class PointerCollector;
T * m_ptr;
};
template <class T>
class PointerCollector
{
public:
PointerCollector() = default;
virtual ~PointerCollector()
{
for (auto &x : m_ptrList)
{
(x.second)->m_ptr = nullptr;
}
}
private:
void addPtr(Pointer<T> *ptr)
{
m_ptrList[ptr] = ptr;
}
void removePtr(Pointer<T> *ptr)
{
m_ptrList.erase(ptr);
}
template<typename T>
friend class Pointer;
std::unordered_map<Pointer<T>*, Pointer<T>*> m_ptrList;
};
class Test : public PointerCollector<Test>
{
public:
Test() {}
~Test() = default;
int getVal() { return m_val; }
private:
int m_val = 100;
};
void func(Pointer<Test> ptr)
{
if (ptr.valid())
{
std::cout << ptr->getVal();
}
else
{
std::cout << "Invalid!\n";
}
}
int main()
{
Test* myTest = new Test();
Pointer<Test> myPtr(myTest);
Pointer<Test> myPtr2(myPtr);
delete myTest;
func(myPtr2);
getchar();
return 0;
}
the Test class will collect the pointers to it and invalidates them if the class gets deleted.
Now i wanted to ask if anyone knows a better implementation or more infomation about this kind of pointer.
I compiled and tested the above code in Visual Studio 2017
The answer is yes, this pattern has been used before by many people. You just created a poor (and broken, because there's at least one outright bug and several things that are sub-optimal) re-implementation of ::std::weak_ptr<T>. You should consider using it instead.

Call descendant's method from ancestor's methods and constructor

Next code presents class-parameter-wrapper, it allows to access underlying class via getters and setters. Simplified version:
template<typename T>
class Parameter
{
public:
typedef T value_type;
typedef Parameter<T> Type;
protected:
T value_;
public:
Parameter() { this->value_ = this->default_value(); }
Parameter(T&& val) { this->set(std::forward<T>(val)); }
Parameter(const T& val) { this->set(std::forward<T>(val)); }
virtual ~Parameter() {};
// Get
T& get() { return this->value_/*this->getter()*/; }
operator T&() { return this->get(); }
// Set
Type& set(T&& val)
{
std::cout << "T&& setter called with " << val << std::endl;
value_ = this->setter(std::forward<T>(val));
return *this;
}
Type& set(const T& val)
{
std::cout << "constT& setter called with " << val << std::endl;
value_ = this->setter(std::forward<const T>(val));
return *this;
}
Type& operator=(T const& val) { return this->set(val); }
Type& operator=(T&& val) { return this->set(val); }
virtual T setter(T const& val) { return val; }
virtual const T& default_value()
{
static const T default_value_{};
return default_value_;
};
};
Using:
int main()
{
struct IncrementorPar : Parameter<int>
{
using Parameter::Parameter; //todo HIDE
using Parameter::operator=; //todo HIDE
virtual int setter(int const& val) { return val + 1; }
virtual const int& default_value(){ return -1; };
} in1(1), in2 = 2, int0;
//assert(int0==int0.default_value()); //FAIL
//assert(int0==-1); //FAIL
//assert(in1 == 2); //FAIL
//assert(in2 == 3); //FAIL
auto *pi1 = new IncrementorPar(2);
//assert(*pi1==3); //FAIL
pi1->set(2);
assert(*pi1==3);
*pi1 = 33;}
}
How could it be possible to call descendant's methods setter() and default_value() from ancestor's constructor?
How can I hide using's?
Not really an elegant solution but...
You could postpone the initialization of value_ using a init() function.
Something like
template<typename T>
class Parameter
{
private:
bool toInit { true };
bool initWithVal;
T valInit;
void init ()
{
if ( initWithVal )
this->set(valInit);
else
value_ = this->default_value();
toInit = false;
}
public:
typedef T value_type;
typedef Parameter<T> Type;
protected:
T value_;
public:
Parameter() : initWithVal{false} { }
Parameter(T&& val) : initWithVal{true}, valInit{std::move(val)} { }
Parameter(const T& val) { this->set(std::forward<T>(val)); }
virtual ~Parameter() {};
// Get
T& get() { if ( toInit ) init(); return this->value_/*this->getter()*/; }
operator T&() { return this->get(); }
// Set
Type& set(T&& val)
{
toInit = false;
std::cout << "T&& setter called with " << val << std::endl;
value_ = this->setter(std::forward<T>(val));
return *this;
}
Type& set(const T& val)
{
toInit = false;
std::cout << "constT& setter called with " << val << std::endl;
value_ = this->setter(std::forward<const T>(val));
return *this;
}
Type& operator=(T const& val) { return this->set(val); }
Type& operator=(T&& val) { return this->set(val); }
virtual T setter(T const& val) { return val; }
virtual const T& default_value()
{
std::cout << "base default value\n";
static const T default_value_{};
return default_value_;
};
};
Explanation
It's not possible to call descendant's methods from ancestor's, without overriding the constructor of each derived class, as during construction, the vtable has information on only the so-far-constructed classes, in the order of constructor calls (which as we recall, is base -> most derived).
Excerpt аrom the forum:
I have a class which calls from its constructor a virtual method Init().
In the descendants I override this virtual method Init(). And the idea is
that whenever I create a descendant, I want the descendant's Init() to be
called, not the ancestors! And I dont want to override the constructor for
that, because I'd have to override the constructors of every descendants
then. How is it possible?
answer
It's not possible without overriding the constructor of each derived class,
as during construction, the vtable has information on only the
so-far-constructed classes, in the order of constructor calls (which as we
recall, is base -> most derived). So when ClassA's constructor gets called,
despite it being an instance of ClassB, the virtual function mechanism will
have access to ClassB's overrides for ClassA's functions only after
ClassA's constructor has finished executing, so anytime you call a virtual
function from ClassA::ClassA(), ClassA::Init() will be called.
-- Dan
Solution
use init guides-variables as #max66 suggested, or something similar.

Calling function with different argument C++

This question is just for improvement purpose. There is a function below:
void Func_A(u8* arg) {
bool local_arg=false;
if(!arg) {
//allocate memory for arg
local_arg=true;
}
//process arg
I am calling this function from multiple places with NULL and non NULL argument.
I just want to ask whther there is a better way of handling such this without local_arg or not.
You can sometimes use...
u8* p = arg ? arg : new u8(...);
...do things with *p...
if (!arg) delete p;
A little fancier, you can write a smart pointer with runtime-configurable ownership:
template <typename T>
class Uncertain_Ownership_Ptr
{
public:
enum Ownership { Own_It, Dont_Own_It };
Uncertain_Ownership_Ptr(T* p, Ownership own) : p_(p), own_(own) { }
Uncertain_Ownership_Ptr(const Uncertain_Ownership_Ptr&) = delete;
void operator=(const Uncertain_Ownership_Ptr&) = delete;
~Uncertain_Ownership_Ptr() { if (own_ == Own_It) delete p_; }
T& operator*() { return *p_; }
const T& operator*() const { return *p_; }
T* operator->() { return p_; }
const T* operator->() const { return p_; }
private:
T* p_;
Ownership own_;
};
...then...
void Func_A(u8* arg)
{
Uncertain_Ownership_Ptr p(arg ? arg : new u8(...),
arg ? Uncertain_Ownership_Ptr::Dont_Own_It : Uncertain_Ownership_Ptr::Own_It);
// use *p ...
}

Delete void* in C++11 using type erasure

I'm trying to fix a double free or corruption in this class:
struct Holder
{
template <typename T>
Holder(const T& v)
{
_v = new T{};
memcpy(_v, &v, sizeof(T));
_deleter = [this]{
if (_v != nullptr)
{
delete reinterpret_cast<T*>(_v);
_v = nullptr;
}
};
}
template <typename T>
T get()
{
T t;
memcpy(&t, _v, sizeof(T));
return t;
}
~Holder()
{
std::cout << "~Holder() " << std::endl;
_deleter();
}
private:
void* _v;
std::function<void()> _deleter;
};
The goal of this class is to Hold a value of a particular type, like boost::any. So I'm trying to understand the mechanism to safely deallocate all memory.
Probably this line of code:
delete reinterpret_cast<T*>(_v);
doesn't do what I expect ...
**** After Suggestions ****
I've rewrite the code using comment suggestions and adding a move constructor
struct Holder
{
template <typename T>
Holder(const T& v)
{
std::cerr << "create " << N << std::endl;
_v = new T(v);
_deleter = [this]{
if (_v != nullptr)
{
std::cerr << "deleter " << N << std::endl;
delete reinterpret_cast<T*>(_v);
_v = nullptr;
}
};
}
Holder(Holder&& rs)
{
_v = rs._v;
_deleter = std::move(rs._deleter);
rs._deleter = []{}; //usefull to avoid a bad function call
}
template <typename T>
T get() const
{
return *reinterpret_cast<T*>(_v);
}
~Holder()
{
//std::cout << "~Holder() " << N << std::endl;
_deleter();
}
private:
void* _v;
std::function<void()> _deleter;
};
Now seems work but I have to manage others corner case :)
Probably the best solution is to use boost::any:
struct Holder
{
template <typename T>
Holder(const T& v)
{
_v = v;
}
template <typename T>
T get()
{
return boost::any_cast<T>(_v);
}
private:
boost::any _v;
};
But I'am trying to understand how it coudl works without it.
This is my last version:
struct Holder
{
template <typename T>
Holder(const T& v)
{
std::cerr << "create " << N << std::endl;
_v = new T(v);
_deleter = [](void* ptr){
if (ptr != nullptr)
{
std::cerr << "deleter " << std::endl;
delete reinterpret_cast<T*>(ptr);
}
};
_builder = [](void* &dest, void* src){
dest = new T(*reinterpret_cast<T*>(src));
};
}
Holder(const Holder& rs)
{
std::cerr << "copy constr" << std::endl;
if (this != &rs)
{
rs._builder(_v, rs._v);
_deleter = rs._deleter;
_builder = rs._builder;
}
}
Holder(Holder&& rs)
{
std::cerr << "move constr" << std::endl;
if (this != &rs)
{
_v = rs._v;
_deleter = std::move(rs._deleter);
_builder = std::move(rs._builder);
rs._deleter = [](void*){};
}
}
Holder& operator=(const Holder& rs)
{
std::cerr << "copy operator" << std::endl;
if (this != &rs)
{
rs._builder(_v, rs._v);
_deleter = rs._deleter;
_builder = rs._builder;
}
return *this;
}
Holder& operator=(Holder&& rs)
{
std::cerr << "move operator" << std::endl;
if (this != &rs)
{
_v = rs._v;
_deleter = std::move(rs._deleter);
_builder = std::move(rs._builder);
rs._deleter = [](void*){};
}
return *this;
}
template <typename T>
T get() const
{
return *reinterpret_cast<T*>(_v);
}
~Holder()
{
//std::cout << "~Holder() " << N << std::endl;
_deleter(_v);
}
private:
void* _v;
std::function<void(void* ptr)> _deleter;
std::function<void(void* &, void* src)> _builder;
};
Don't reimplement the horse.
using pvoid_holder = std::unique_ptr<void, std::function<void(void*)>>
template<class T>
pvoid_holder pvoid_it( T* t ) {
return { t, [](void* v){ if (v) delete static_cast<T*>(v); } };
}
Now store a pvoid_holder in your Holder class. It will handle memory lifetime for you.
You could use a naked pvoid_holder, but it might have a richer interface than you want (for example, it will allow the stored pointer to be changed without changing the deleter).
You can also replace std::function with void(*)(void*) for a marginal performance gain.
Here is a random idea. I still don't like it though. The whole idea behind this design is bad.
template <typename T>
struct Holder
{
public:
Holder(T const& v)
{
new (&m_v) T(v);
}
T const& get() const
{
return reinterpret_cast<T const&>(m_v);
}
T& get()
{
return reinterpret_cast<T&>(m_v);
}
~Holder()
{
std::cout << "~Holder() " << std::endl;
get().~T();
}
private:
char m_v[sizeof(T)];
};
This class doesn't do the same as yours anymore, ie it can't store arbitrary types in a std::vector<Holder> but only the same type (std::vector<Holder<Foo>>). A comment was too small to contain this code though and I wanted to show a better looking syntax for what you're playing with ;).
That being said, the only way you can do what you're trying to do is when you add a second layer for the reference counting. Ie, you replace your void* _v with something that resembles shared_ptr but which doesn't call delete when the count reaches zero but calls deleter (which therefore should be stored inside this new class). In fact your class looks mostly like this new class, except that you should make it non-copyable and provide reference counting (ie through boost::intrusive_ptr). Then Holder can be a wrapper around that that is copyable.
Probably this line of code: delete reinterpret_cast<T*>(_v); doesn't do what I expect ...
Not exactly. Your types are likely using a default copy ctor; this copies your data pointer _v, and your deleter. So when both objects destruct, both deleters trigger, causing the data to be deleted twice. (Side note--you shouldn't name variables starting with _; such identifiers are reserved for implementations).
Here's what it takes to do type erasure properly, assuming I've no bugs in it. A better way would be to stick to using boost::any.
#include <utility>
struct EmptyType {}; // Thrown if unexpectedly empty
struct InvalidType {}; // Thrown if Holder(T) but get<U>.
struct Holder
{
Holder()
: data_()
, deleter_(e_deleter)
, copier_(e_copier)
, typetag_()
{
}
template<typename T>
Holder(const T& t)
: data_(erase_cast(new T))
, deleter_(deleter<T>)
// Need to explicitly carry T's copy behavior
// because Holder's default copy ctor isn't going to
, copier_(copier<T>)
// You need some way to protect against getting
// an Orange out of a Holder that holds an Apple.
, typetag_(id<T>())
{
}
Holder(const Holder& rhs)
: data_(rhs.copy())
, deleter_(rhs.deleter_)
, copier_(rhs.copier_)
, typetag_(rhs.typetag_)
{
}
template<typename T>
T get()
{
if (!data_) throw EmptyType();
T rv(fetch<T>());
return rv;
}
Holder(Holder&& rhs)
: data_()
, copier_(rhs.copier_)
, deleter_(rhs.deleter_)
, typetag_(rhs.typetag_)
{
std::swap(data_, rhs.data_);
}
~Holder()
{
destroy();
}
private:
// Reinterpret_cast wrappers labeled semantically
template<typename T>
static void* erase_cast(T* t) { return reinterpret_cast<void*>(t); }
template<typename T>
static T* unerase_cast(void* t) { return reinterpret_cast<T*>(t); }
// Return a data copy
void* copy() const { return copier_(data_); }
// Return const reference to data
template<typename T>
const T& fetch() {
if (typetag_!=id<T>()) throw InvalidType();
return *unerase_cast<T>(data_);
}
// Destroy data
void destroy() { deleter_(data_); data_=0; }
// ==== Type erased copy semantics ===
void*(*copier_)(void*);
template<typename T>
static void* copier(void* v) {
return erase_cast<T>(new T(*unerase_cast<T>(v)));
}
static void* e_copier(void*) { return 0; }
// ==== Type erased delete semantics ===
void(*deleter_)(void*);
template<typename T>
static void deleter(void* v) {
delete unerase_cast<T>(v);
}
static void e_deleter(void*) {}
// ==== Type protection using tagging (could also use typeid)
static int makenewid() { static int i=0; return i++;}
template<typename T>
static int id() { static int i=makenewid(); return i; }
// Type erased data
void* data_;
// Type erased tag
int typetag_;
};
...and here is some test/demo code:
#include <iostream>
#include <vector>
#define FAIL() std::cout << "Fail" << std::endl; return 1
int foos=0;
struct Foo { Foo(){++foos;} Foo(const Foo&){++foos;} ~Foo(){--foos;} };
int bars=0;
struct Bar { Bar(){++bars;} Bar(const Bar&){++bars;} ~Bar(){--bars;} };
int main() {
{
std::vector<Holder> v;
Foo fx,fy,fz; Bar ba,bb;
v.push_back(fx); v.push_back(fy); v.push_back(fz);
v.push_back(ba); v.push_back(ba); v.push_back(bb);
v.push_back(Holder());
try {
Foo y = v[2].get<Foo>();
}
catch (EmptyType&) { FAIL(); }
catch (InvalidType&) { FAIL(); }
try {
Foo y = v[4].get<Foo>();
FAIL();
}
catch (EmptyType&) { FAIL(); }
catch (InvalidType&) { }
try {
Foo y = v[6].get<Foo>();
FAIL();
}
catch (EmptyType&) { }
catch (InvalidType&) { FAIL(); }
}
if (foos||bars) { FAIL(); }
std::cout << "Pass" << std::endl;
}
Test results:
$ ./a.exe
Pass

struct forward declaration and copy constructor

My abstract Reference counter class:
template<class T>
class ReferenceCounter
{
public:
ReferenceCounter();
~ReferenceCounter();
void addRef();
void release();
uint32 getCountReferences() const;
protected:
int32* pCountReferences;
virtual void destroyObject() = 0;
virtual void shallowCopy(const T& rhs) = 0;
};
template<class T>
inline ReferenceCounter<T>::ReferenceCounter()
{
pCountReferences = new int32;
*pCountReferences = 1;
}
template<class T>
inline ReferenceCounter<T>::~ReferenceCounter()
{
if(pCountReferences != NULL && *pCountReferences == 0)
{
delete pCountReferences;
pCountReferences = NULL;
}
}
template<class T>
inline void ReferenceCounter<T>::addRef()
{
debug_assert((*pCountReferences) >= 0, "Incorrect value of count references");
++(*pCountReferences);
}
template<class T>
inline void ReferenceCounter<T>::release()
{
debug_assert((*pCountReferences) > 0, "Incorrect value of count references");
(*pCountReferences)--;
if(pCountReferences != NULL && *pCountReferences == 0)
{
destroyObject();
}
}
template<class T>
inline uint32 ReferenceCounter<T>::getCountReferences() const
{
return *pCountReferences;
}
This is my smart pointer :
template<class T>
class SmartPtr
{
public:
SmartPtr();
SmartPtr(T* pInst);
SmartPtr(const SmartPtr<T>& rhs);
~SmartPtr();
void operator = (const SmartPtr<T>& rhs);
T* operator -> () const;
T* getData() const;
bool isNULL() const;
private:
T* pInst;
};
template<class T>
SmartPtr<T>::SmartPtr() : pInst(NULL) {}
template<class T>
SmartPtr<T>::SmartPtr(T* pInst) : pInst(pInst) {}
template<class T>
SmartPtr<T>::~SmartPtr()
{
if(pInst != NULL)
{
pInst->release();
}
}
template<class T>
SmartPtr<T>::SmartPtr(const SmartPtr<T>& rhs)
{
this->pInst = rhs.pInst;
if(pInst != NULL)
{
pInst->addRef();
}
}
template<class T>
void SmartPtr<T>::operator= (const SmartPtr<T>& rhs)
{
this->pInst = rhs.pInst;
if(pInst != NULL)
{
pInst->addRef();
}
}
template<class T>
T* SmartPtr<T>::operator->() const
{
return pInst;
}
template<class T>
T* SmartPtr<T>::getData() const
{
return pInst;
}
template<class T>
bool SmartPtr<T>::isNULL() const
{
return pInst == NULL;
}
There are test of code :
#include <iostream>
#include "ReferenceCounter.h"
#include "SmartPtr.h"
using namespace std;
class B;
class A : public ReferenceCounter<A>
{
public:
A();
A(const A& rhs);
~A();
SmartPtr<B> getB();
void operator = (const A& rhs);
private:
void destroyObject();
void shallowCopy(const A& rhs);
};
class B : public ReferenceCounter<B>
{
private:
void destroyObject() {} ;
void shallowCopy(const B& rhs) {};
};
A::A()
{
cout << "Create object" << endl;
}
A::A(const A& rhs)
{
shallowCopy(rhs);
addRef();
cout << "copy constructor " << endl;
}
A::~A()
{
release();
}
void A::destroyObject()
{
cout << "destroy" << endl;
}
void A::shallowCopy(const A& rhs)
{
this->pCountReferences = rhs.pCountReferences;
}
void A::operator = (const A& rhs)
{
shallowCopy(rhs);
addRef();
cout << "operator = " << endl;
}
SmartPtr<B> A::getB()
{
return SmartPtr<B>(new B());
}
SmartPtr<A> getA()
{
SmartPtr<A> a(new A());
return a;
}
int main()
{
getA();
return 0;
}
This code is worked but below not called copy constructor of smart pointer when i debug this code . What problems happens below ??
int main()
{
A a;
a.getB();
}
See here for Return value optimization.
The compiler is allowed, to eliminate the copy of a temporary object being returned.
With C++11, there's also the possibility of moving an object. See What are move semantics? for an explanation.
Update:
This is not a problem at all, just a compiler optimization.
As long as there's nothing special going on in your constructor and destructor, there's no need to prevent this optimization. You should allow this instead, because it makes your program run faster by skipping one constructor and one destructor call.