I understand that pointer has reference to object? In order not to duplicate it
class A
{
A(){};
}
A *ptrA;
why do we need a pointer to own class?
how does it work?
The type of ptrA is A * which mean class A pointer, so, ptrA is pointer of type class A.
It can hold the reference of memory of object of type A.
Example:
#include <iostream>
class A {
public:
A() {
std::cout << "Constructor" << std::endl;
}
void test() {
std::cout << "test() member function" << std::endl;
}
~A() {
std::cout << "Destructor" << std::endl;
}
};
int main() {
A* ptrA = new A(); // Dynamic allocation of object of type A
ptrA->test();
delete ptrA; // Delete the object created dynamically
A objA; // object of type A created locally
ptrA = &objA; // ptrA assigned address of object objA
ptrA->test();
return 0;
}
Related
How can we pass a function pointer as an argument? For example, the function pointer myFunPtr is an argument when calling class A and I need this pointer to point to function funcB in class B
#include <iostream>
typedef void(*myFunPtr)(void);
class A {
public:
A(myFunPtr ptr);
virtual ~A();
myFunPtr funptr;
};
A::A(myFunPtr ptr){
std::cout << "Constructor A \n";
funptr = ptr;
}
A::~A(){}
///////////////
class B {
public:
B();
virtual ~B();
void funcB();
};
B::B(){
std::cout << "Constructor B \n";
A *objA = new A(funcB);
}
B::~B(){}
void B::funcB(){
std::cout << " call B::funcB \n";
}
///////////////
int main(){
B *objB = new B();
delete objB;
return 0;
}
This is a function pointer type to a free function (not a class member function):
typedef void(*myFunPtr)(void);
This is a B member function pointer type:
typedef void(B::*myFunPtr)(void);
Demo
Here's another Demo that will call a member function in a B. To do that, a pointer to a B and a pointer to a B member function is stored in A.
I'm struggled over some code where I don't know how to name it and how to solve it. I tried to reduce the code to the following example (so the example itself won't make sense, but it shows the problematic):
struct MyInterface {
virtual ~MyInterface() {
};
virtual void Output() = 0;
};
class A {
public:
MyInterface *myInterface;
A(MyInterface *myInterface) {
std::cout << "this in A constructor: " << this << std::endl;
this->myInterface = myInterface;
}
void CallA() {
this->myInterface->Output();
}
};
class B : public MyInterface, A {
public:
int v;
B(int v) : A(this) {
std::cout << "this in B constructor: " << this << std::endl;
this->v = v;
}
virtual void Output() override {
std::cout << "Whatever" << std::endl;
}
void CallB() {
std::cout << "this in CallB: " << this << std::endl;
this->CallA();
}
};
class Foo {
public:
B b;
Foo() : b(42) {
b = B(41); //This will make an "invalid" B:
//generates B on the Stack but assign the bytes to Foo.b (which is on the the heap)
//so b.myInterface will point to the stack
//after leaving this context b.other will be invalid
}
void Exec() {
b.CallB();
}
};
int main(int argc, char **args) {
Foo *foo = new Foo();
foo->Exec(); //Gives a segfault, because foo->b.myInterface is not valid
return 0;
}
First I thought it has something to do with the inheritance and its virtual methods. But I think the main problematic is the this pointer within the constructors.
So my questions: When b is constructed, the this pointer in the constructors points to the stack. Why doesn't show the this pointer to the target memory (in the heap)? No copy constructor is called - Why?
How can I Name this problem?
The copy constructor isn't called because you aren't creating a new object you are assigning to an existing object. This calls the assignment operator.
This is copy construction:
B b1(42); // construction
B b2(b1); // copy construction
B b3 = b1; // looks like assignment but is actually copy construction
This is assignment:
B b1(42); // construction
b1 = B(43); // b1 already exists we can't copy construct, construct a new object and assign to b1
You need to override the assignment operator:
class B
{
B& operator=(const B& other)
{
// fix references to this here
}
}
I am learning about polymorphism, and this is something I have stumbled on. I cant find satisfying answer and testing the following code doesnt yield expected result.
#include <stdio.h>
#include <iostream>
class Base {
public:
Base(){
std::cout<<"Constructing Base" << std::endl;
};
virtual int get_a(){
return p_a;
};
virtual int check(){
std::cout<<"check Base" << std::endl; return 2;
};
virtual ~Base(){
std::cout<<"Destroying Base" << std::endl;
};
int p_a = 4;
};
class Derive: public Base {
public:
Derive(){
std::cout<<"Constructing Derive" << std::endl;
};
int get_a(){
return p_a;
};
int check(){
std::cout<<"check Derive" << std::endl;
return 3;
};
~Derive(){ std::cout<<"Destroying Derive" << std::endl; };
int p_a = 2;
};
int main() {
Base *basePtr = new Derive();
delete basePtr;
basePtr->check();
std::cout << "p_a: " << basePtr->get_a() << std::endl;
return 1;
}
Console output :
Constructing Base // line 1
Constructing Derive // line 2
Destroying Derive // line 3
Destroying Base // line 4
check Base // line 5
p_a: 4 // line 6
I see why I get line 1-4, the basePtr is pointer to Derive, which inherits from Base, which implements virtual functions.
My 1. expectation : After calling delete, the pointer basePtr should not be able to deliver the function call ->check(), and also there should be no value p_a.
My 2. expectation : I would expect the value p_a from Derive (p_a = 2), to appear on the output, because basePtr stores the pointer of Derive.
Could someone correct my thinking ?
This is undefined behavior. Whatever results you get, are invalid.
delete basePtr;
This destroys the object.
basePtr->check();
After destroying the object, the shown code attempts to dereference a pointer to the destroyed instance of the class, and invoke a method of the destroyed object. Invoking a method of a destroyed object is undefined behavior.
A has a static function A::create() that creates an instance of A, does some initialization, and returns a pointer to it.
I want to create a subclass of A and have a similar create() func:
class B : public A {
public:
static B* create();
int val;
//...
}
in this B::create() function I have to do the following:
B* B::create() {
auto b = (B*)A::create();
b -> val = 0;
//...
return b;
}
Is this the right way to do it? What will happen after the cast?
Follow-up: A has a protected/private constructor, How should I write B::create(), or B's constructor? I do want the vars inherited from A to have the same values as those created by A::create() would have
The cast won't do anything sensible unless A::create() returns a pointer to a B object. If A::create() returns a pointer to an object which isn't a B you have undefined behavior.
In C++ you deal with initialization of objects using constructors: the initialization of base classes is inherited and each derived can do whatever custom initialization it needs to do. Your B::create() would just return a suitably constructed object:
B::B()
: A() // initialize base
, val(0) {
// other initialization
}
B* B::create() { return new B(); }
You could make class B a friend of A like this
class A {
public:
static A* createA();
int varA;
private:
friend class B; // Make B a friend so that B can use private constructor of A
A()
{
cout << "In A constructor" << endl;
varA = 5; // Initialize members of A here
}
};
A* A::createA()
{
return new A;
}
class B : public A {
public:
static B* createB();
int varB;
private:
B()
{
cout << "In B constructor" << endl;
varB = -5; // Initialize members of B here
}
};
B* B::createB()
{
return new B;
}
int main()
{
cout << "Create A" << endl;
A* x=A::createA();
cout << "x->varA is " << x->varA << endl;
cout << endl;
cout << "Create B" << endl;
B* y=B::createB();
cout << "y->varA is " << y->varA << endl;
cout << "y->varB is " << y->varB << endl;
cout << endl;
delete x;
delete y;
}
When a new B is made, the constructor of A get called automatically and the members of A will be initialized.
Output is:
Create A
In A constructor
x->varA is 5
Create B
In A constructor
In B constructor
y->varA is 5
y->varB is -5
Another way is to make the constructor of A protected instead of private.
I'm getting confused why p->a() is calling B::a()?. Is there a paragraph somewhere in the C++ documentation/standard that describes this behavior well?
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "A ctor" << endl; a_instance = this; }
static A *get_instance() { return a_instance; }
static A *a_instance;
void virtual a() { cout << "From base class" << endl; }
};
class B : public A {
public:
B() { cout << "B ctor" << endl; b_instance = this; }
static B *get_instance() { return b_instance; }
static B *b_instance;
void virtual a() { cout << "From derived class" << endl; }
};
A *A::a_instance = 0;
B *B::b_instance = 0;
main()
{
cout << "Create A" << endl;
A ab;
cout << "Create B" << endl;
B abc;
B *ptr = B::get_instance();
A *p = A::get_instance();
cout << "Called from A object type" << endl;
if (p) {
p->a();
}
}
When you create the variable abc, A's constructor sets a_instance to that instance. Despite p being a pointer to an A, since the instance is pointing to a B, it's correctly calling B::a().
To fix this behaviour, you could use the following:
A* A::get_instance()
{
static A a;
return &a;
}
B* B::get_instance()
{
static B b;
return &b;
}
and remove all code that has to do with a_instance and b_instance.
The B constructor calls the A constructor first. That replaces the a_instance that you'd already created.
This chaining of constructors is well defined in the standard. The base is always called first, so that the derived constructor is guaranteed to be working on a valid base object.
What you are experiencing is caused by the design error, which is based on A's constructor initializing the static member using this. Body of this constructor is invoked not only when you are creating the instance of A but also when you are creating the instance of any of its derived classes:
A() { /* ... */ a_instance = this; }
So when you create an instance of type B, before the body of B's constructor is executed, the body of A's constructor is executed at first - this overwrites member a_instance with this within a context of instance of type B, i.e. it makes a_instance to point to this new instance of type B.
What you could do is to place a static variable inside of the getInstance method:
class A
{
public:
static A* getInstance() {
static A s; // <-- instantiated upon first call
return &s;
}
void virtual foo() { std::cout << "From base class" << std::endl; }
protected:
A() { } // <-- protected constructor
~A() { }
A(const A&); // <-- protected copy constructor
A& operator=(const A&); // <-- protected assignment operator
};
then B:
class B : public A
{
public:
static B* getInstance() {
static B s; // <-- instantiated upon first call
return &s;
}
void virtual foo() { std::cout << "From derived class" << std::endl; }
protected:
B() { } // <-- protected constructor
~B() { }
B(const B&); // <-- protected copy constructor
B& operator=(const B&); // <-- protected assignment operator
};
and possible usage:
int main() {
A::getInstance()->foo();
B::getInstance()->foo();
}
that outputs:
From base class
From derived class
B constructor invokes A constructor...