I do not understand why the code below calls the base's class (=A) implementation of the
A::operator=(A&)
(indicated by output lines 15. and 17.) whenever the reference passed in as an argument are of the derived class type. Since all pointers point to objects of the derived class I would expect the same behaviour (=calling the operator from the derived class B) for all calls.
Output when executing the below listed code:
- A::Ctor objID=1280 text=BObject1
- B::Ctor objID=1280 text=BObject1
- A::Ctor objID=3279 text=BObject2
- B::Ctor objID=3279 text=BObject2
- --- ptrA->print():
- B::print() objID=1280 text=BObject1
- B::print() objID=3279 text=BObject2
- --- *ptrAObj1 = *ptrAObj2:
- B::operator=(A&) objID=1280 text=BObject1
- --- ptrAObj1->operator=(*ptrAObj2):
- B::operator=(A&) objID=1280 text=BObject2
- --- *ptrBObj1 = *ptrAObj2:
- B::operator=(A&) objID=1280 text=BObject2
- --- *ptrBObj1 = *ptrBObj2:
- A::operator=(A&) objID=1280 text=BObject2
- --- ptrBObj1->operator=(*ptrBObj2):
- A::operator=(A&) objID=1280 text=BObject2
- --- ptrAObj1->operator=(*ptrBObj2):
- B::operator=(A&) objID=1280 text=BObject2
- ---- TearDown()
- B::Dtor objID=1280 text=BObject2
- A::Dtor objID=1280 text=BObject2
- B::Dtor objID=3279 text=BObject2
- A::Dtor objID=3279 text=BObject2
Code:
#include "gtest/gtest.h"
#include <stdio.h>
#include <string>
#include <ctime>
class A
{
public:
A(const std::string& sLabel=""):
m_sText(sLabel)
{
std::srand(std::time(nullptr)); // use current time as seed for random generator
int random_no = (std::rand()+(m_iObjectCounter*1999)) % 9999;
m_iObjectID = random_no;
m_iObjectCounter++;
std::cout << "A::Ctor objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual ~A()
{
std::cout << "A::Dtor objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual void print() const
{
std::cout << "A::print() objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual int operator=(A& rIn)
{
std::cout << "A::operator=(A&) objID=" << m_iObjectID << " text=" << m_sText << std::endl;
m_sText = rIn.m_sText;
return EXIT_SUCCESS;
}
std::string m_sText;
int m_iObjectID;
static int m_iObjectCounter;
};
int A::m_iObjectCounter=0;
class B : public A
{
public:
B(const std::string& sLabel = "") :
A(sLabel)
{
std::cout << "B::Ctor objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual ~B()
{
std::cout << "B::Dtor objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual void print() const
{
std::cout << "B::print() objID=" << m_iObjectID << " text=" << m_sText << std::endl;
}
virtual int operator=(A& rIn)
{
std::cout << "B::operator=(A&) objID=" << m_iObjectID << " text=" << m_sText << std::endl;
m_sText = rIn.m_sText;
return EXIT_SUCCESS;
}
};
class TestAssignmentOperator : public ::testing::Test {
public:
TestAssignmentOperator() :
ptrAtoBObject1(NULL),
ptrAtoBObject2(NULL)
{
ptrAtoBObject1 = new B("BObject1");
ptrAtoBObject2 = new B("BObject2");
}
void SetUp(){}
void TearDown() {
std::cout << " ---- TearDown()" << std::endl;
delete ptrAtoBObject1;
delete ptrAtoBObject2;
}
~TestAssignmentOperator(){}
A* ptrAtoBObject1;
A* ptrAtoBObject2;
};
TEST_F(TestAssignmentOperator, Test1)
{
std::cout << " --- ptrA->print():" << std::endl;
ptrAtoBObject1->print();
ptrAtoBObject2->print();
int iError = EXIT_FAILURE;
std::cout << " --- *ptrAObj1 = *ptrAObj2:" << std::endl;
iError = *ptrAtoBObject1 = *ptrAtoBObject2;
std::cout << " --- ptrAObj1->operator=(*ptrAObj2):" << std::endl;
iError = ptrAtoBObject1->operator=(*ptrAtoBObject2);
std::cout << " --- *ptrBObj1 = *ptrAObj2:" << std::endl;
B* ptrBToObject1 = dynamic_cast<B*>(ptrAtoBObject1);
iError = *ptrBToObject1 = *ptrAtoBObject2;
std::cout << " --- *ptrBObj1 = *ptrBObj2:" << std::endl;
B* ptrBtoBObject2 = dynamic_cast<B*>(ptrAtoBObject2);
*ptrBToObject1 = *ptrBtoBObject2;
std::cout << " --- ptrBObj1->operator=(*ptrBObj2):" << std::endl;
ptrBToObject1->operator=(*ptrBtoBObject2);
std::cout << " --- ptrAObj1->operator=(*ptrBObj2):" << std::endl;
ptrAtoBObject1->operator=(*ptrBtoBObject2);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}