Passing pointer to self - c++

C++ I have a window class, parent, that creates several tab windows, child1, child2, ect..
The parent window has member variables for each child window. I want to access child2 from child1 and thought I might be able to pass a pointer to parent in the constructor of child1 and use parent's pointer to access child2. I don't even really know how to get started. I have tried something like the following and it doesn't compile, starting with the line containing (*this).
class CParent
{
public:
CParent() {};
CChild1 m_Child1(*this);
CChild2 m_Child2;
....
};
class CChild1
{
public:
CChild1(CParent *pParent) {};
int getChild2Number(return pParent->m_Child2.m_number);
};
class CChild2
{
public:
CChild2() {};
m_number = 1;
}
I was wondering if anyone could help out with
1. Getting this to compile without changing up the structure too much
2. Advice on a better way to set this relationship up.

Use the initializer list for the children and pass this. However, be aware that some uses of this are incorrect inside an initializer list (since the object is still under construction and some members will not be initialized yet).
If m_Child1 needs to use m_Child2, you should put m_Child2 above m_Child1 in the class definition so it will be initialized first. Then you can pass the this pointer to m_Child2 like this:
struct CParent {
CParent() : m_Child1( this ) { }
private:
CChild2 m_Child2;
CChild1 m_Child1;
};
You might consider passing just m_Child2 to m_Child1, though, to make the data dependency explicit, to give a hint why m_Child2 must come first, and to not provide a reference to an object under construction. That would look like this:
struct CChild2; // Forward declare the class so CChild1 can accept it
struct CChild1 { // Define CChild1 first because CParent uses it for a member
CChild1( CChild2 &child2 );
// ...
};
// ...
struct CParent {
CParent() : m_Child1( m_Child2 ) { }
private:
CChild2 m_Child2;
CChild1 m_Child1;
};

Your code has several severe issues concerning declaration and definition syntax, member initialization etc. My advise is to keep going with C++ basics.
I suggest to use a dynamic storage for your children since your questions gives a hint that there may be more than two of them.
class CParent;
class CChild
{
public:
CChild (CParent * p_parent);
int get_other_child_number(size_t const other_child);
int number (void) { return m_number; }
private:
CParent * m_parent;
int m_number;
};
class CParent
{
public:
CParent (void) { }
void add_child (void) { m_children.emplace_back(this); }
CChild & child (size_t const child_num) { return m_children.at(child_num); }
CChild const & child (size_t const child_num) const { return m_children.at(child_num); }
size_t num_childs (void) const { return m_children.size(); }
private:
std::vector<CChild> m_children;
};
CChild::CChild (CParent * p_parent) : m_parent(p_parent), m_number(p_parent->num_childs()) { }
int CChild::get_other_child_number(size_t const other_child)
{
return m_parent->child(other_child).number();
}
int main()
{
CParent par;
par.add_child();
par.add_child();
cout << "Number of Child 0 is " << par.child(0).number() << endl;
cout << "Number of Child 1 is " << par.child(1).number() << endl;
cout << "Number of Child 0 from Child 1 is " << par.child(1).get_other_child_number(0) << endl;
cout << "Number of Child 1 from Child 0 is " << par.child(0).get_other_child_number(1) << endl;
}

Related

How to identify the vector classes which override from different child classes?

I would like to identify which child classes initialize pointers in a vector.
I prepare a vector that contains different types of override classes. After that, I set it as an argument in the same function. In the function, I would like to identify which classes initialize this argument and apply different processes for each class.
This is the code and current output.
#include <memory>
#include <iostream>
#include <vector>
class Parent
{
public:
Parent() {};
virtual ~Parent() {};
virtual void print()
{
std::cout << "I am parent!" << std::endl;
}
};
class ChildA : public Parent
{
public:
ChildA() {};
~ChildA() {};
void print() override
{
std::cout << "I am child A!" << std::endl;
}
};
class ChildB : public Parent
{
public:
ChildB() {};
~ChildB() {};
void print() override
{
std::cout << "I am child B!" << std::endl;
}
};
void func(std::unique_ptr<Parent>& pa)
{
pa->print();
//if (pa is initialized from Parent)
//{
//}
//if (pa is initialized from ChildA)
//{
//}
//if (pa is initialized from ChildB)
//{
//}
return;
}
int main(int argc, char** argv)
{
std::unique_ptr<Parent> pa = std::make_unique<Parent>();
std::unique_ptr<ChildA> chA = std::make_unique<ChildA>();
std::unique_ptr<ChildB> chB = std::make_unique<ChildB>();
std::vector<std::unique_ptr<Parent>> mList;
mList.push_back(std::move(pa));
mList.push_back(std::move(chA));
mList.push_back(std::move(chB));
for (auto& l : mList)
func(l);
return 0;
}
output
I am parent!
I am child A!
I am child B!
Could you tell me any idea?
Thank you.
The purpose of doing polymorphic code with virtual functions is usually so you can avoid doing "is this an X" style tests. Instead you create a virtual function doSpecialStuff in the base class and call it via a base class pointer (like print in your code), which then does the appropriate operations for each derived class.
If you really want to test the type, use dynamic_cast:
if(auto child_ptr=dynamic_cast<ChildA*>(pa.get())){
child_ptr->child_A_function();
}

Nested struct attributes inheritance

I read that you can extend a structure by using inheritance. I have a derived class in which I want to have the same struct that its parent but extended with more fields. This seems to work, however when I call a method from the Parent class that modified the structure, it does not have effect in the Child structure attribute. Here, an example of what am I trying:
class Parent
{
public:
struct info
{
int a;
};
info data;
virtual void main(void);
};
void Parent::main()
{
data.a =1;
}
class Child: public Parent
{
public:
struct info2: public info
{
int b;
};
info2 data;
virtual void main(void);
};
void Child::main(void)
{
Parent::main();
data.b = 2;
std::cout << data.a << "\n";
std::cout << data.b << "\n";
}
int main(void)
{
Parent *base;
Child derived;
base = &derived;
base->main();
return 0;
}
This instead of printing 1 and 2 prints 0 and 2. So basically as if the attribute data from the derived class is not modified by the call to Parent::main.
What the right way of doing that? Am I completely doing it wrong?
You mean
void Child::main(void)
{
Parent::main();
data.b = 2;
std::cout << Parent::data.a << "\n";
std::cout << data.b << "\n";
}
The name data declared in the derived class hides the name data declared in the base class. So you need to use a qualified name to access a hidden member of the parent class.
As for data member a of the member data of the derived class then it was not initialized.
Objects of the derived class have two data members data: one is inherited with the type info (which name is hidden in the derived class) and other is the own data member of the derived class.
The base class knows nothing about the data member data of the derived class.
You could define a virtual function within the class info. For example
#include <iostream>
class Parent
{
public:
struct info
{
int a;
virtual void set( int a )
{
this->a = a;
}
};
info data;
virtual void main(void);
};
void Parent::main()
{
data.set( 1 );
}
class Child: public Parent
{
public:
struct info2: public info
{
int b;
void set( int a ) override
{
this->a = a;
}
};
info2 data;
virtual void main(void);
};
void Child::main(void)
{
data.set( 3 );
data.b = 2;
std::cout << data.a << "\n";
std::cout << data.b << "\n";
}
int main(void)
{
Parent *base;
Child derived;
base = &derived;
base->main();
return 0;
}
The program output is
3
2
You're entirely correct, Parent::main() is unable to access Child::data, and knows nothing about any mythical info2 type; to it, Parent::data is all there is, and info is its type.
There are a few easy ways to make Child::main() work with Child::data instead of Parent::data, or to make it access the desired field from each version, but I suspect that's not what you're after. If you want both Parent and Child to see the same data (as an info and an info2, respectively), then data should itself be used polymorphically. For this example, I'll use a regular pointer for simplicity (and in turn, operator. will be replaced with operator->, when accessing data's members), but I would recommend looking into smart pointers such as std::unique_ptr to simplify the memory management.
class Parent
{
public:
struct info
{
int a;
// Chances are, it's going to be deleted through an info* no matter what it is. Therefore, virtual destructor.
virtual ~info() = default;
};
info* data; // Consider using a smart pointer here, like std::unique_ptr.
virtual void main(void);
virtual void output() const; // Just adding this for convenience.
// Default constructor now allows data to be supplied, or creates it if necessary.
Parent(info* dp = nullptr) : data(dp ? dp : new info) {}
// Correct destructor will always be called.
virtual ~Parent() { if(data) { delete data; } }
};
void Parent::main()
{
data->a =1;
}
We now remove the field Child::data, and instead have Child supply its desired data to Parent's constructor.
class Child: public Parent
{
public:
struct info2: public info
{
int b;
};
//info2 data;
virtual void main(void);
void output() const override; // Just adding this for convenience.
Child() : Parent(new info2) {}
};
Child will, when required, view data as an info2 instead of an info.
void Child::main(void)
{
Parent::main();
auto dataPtr = static_cast<info2*>(data); // In Child, we know data is an info2*.
dataPtr->b = 2;
// Just gonna move these to output(), for a cleaner illustration.
//std::cout << "Data->a: " << data->a << "\n";
//std::cout << "Data->b: " << dataPtr->b << "\n";
}
This will then cause data to work as desired, with Parent and Child both having the correct type.
void Parent::output() const {
std::cout << "Parent:\n";
std::cout << "> Data->a: " << data->a << "\n";
}
void Child::output() const /*override*/ {
std::cout << "Child as ";
Parent::output();
auto dataPtr = static_cast<info2*>(data);
std::cout << "Child:\n";
std::cout << "> Data->a: " << dataPtr->a << "\n";
std::cout << "> Data->b: " << dataPtr->b << "\n";
}
This will then perform as expected, as seen live on Coliru. Note that if you want to be able to, e.g., create a Child from a pre-existing Parent, you'll want to add a move constructor that can make an info2 from an info; you should consider following the Rule of Five, or using a smart pointer instead of a raw pointer. ;P
You have to use the below code:
void Child::main(void)
{
Parent::main();
data.b = 2;
std::cout << Parent::data.a << "\n";
std::cout << data.b << "\n";
}

Objects counters

I would like to have to counters for each class type that that was ever instantiated. As a starting point someone sugested this approach as an example:
class Person
{
public:
Person() {
objects.push_back(this);
}
virtual ~Person() {
objects.erase(this);
}
static void print_types()
{
for (auto pers : container)
{
std::cout << typeid(*pers).name() << "\n";
}
}
private:
static std::set<const Person*> objects;
};
class Employee : public Person
{
};
class Employee2 : public Employee
{
};
Each time one of the classes is instatiated I keep track of the objects and I can use print_types() to know how many of which type I've created so far. Notice that Employee2 inherits from Employee and not from Person (i need this to work for chain inheritance)
I would like to extend this so that I have two counters per type: created and alive. The problem is that you can't easily mantain the counters from the constructor/destructor of the base class, Person, because typeid(*this) will return the base class type when called from constructor/destructor.
Another suggestion was to use CRTP pattern but this doesn't work when you use chained inheritance.
Is there another way to implement such counters ?
I just played around a bit. Maybe this helps you. It always prints the value of the right class (not the base class).
But it's practically the same^^.
Header:
#include <set>
#include <string>
class observeable;
class observer
{
public:
observer() = delete;
static void print();
static std::set< observeable* > items;
};
class observeable
{
public:
observeable();
virtual ~observeable();
virtual std::string get_typeid();
};
Source:
std::set< observeable* > observer::items;
void observer::print()
{
std::cout << "Called" << std::endl;
for( auto item : items )
std::cout << item->get_typeid() << std::endl;
}
observeable::observeable()
{
observer::items.insert( this );
}
observeable::~observeable()
{
observer::items.erase( this );
}
std::string observeable::get_typeid()
{
return std::string( typeid(*this).name() );
}
Main:
#include <memory>
class A : observeable
{};
class B : A
{};
class C : observeable
{};
int main()
{
A a;
B b;
observer::print(); // A B present
{
C d;
}
observer::print(); // no C present
auto d_heap = std::shared_ptr<C>( new C() );
observer::print(); // C present
return 0;
}

Passing array pointer from derived class to base class C++

I'm trying to understand inheritance in C++.
I want to dynamically create an array in a derived class and pass the array pointer to the base class, and then the base class fills in the array. Finally I want to print the array from the derived class.
I wrote the following code but when I run this, the program crashes and I get a segmentation fault error.
How should I implement this?!
class Base {
private:
int* array;
public:
Base(int* a) {
array = a;
for(int i = 0 ; i < 10 ; i++) {
array[i] = i;
}
}
};
class Child : public Base {
private:
int* array;
public:
Child() : array(new int[10]), Base(array) {}
void print() {
for(int i = 0 ; i < 10 ; i++) {
cout << array[i] << endl;
}
}
};
The problem here is that the order of items in the initializer list does not influence the order in which the initialization is actually performed; only the order in which the members are declared is considered. Moreover, the initialization of the base always happens first.
Therefore, the Child constructor is actually executed as follows:
Base(array) is invoked (array is not set here!)
array is assigned a valid value.
Fortunately, all you need to do to fix this problem is to remove the array from the Child: it is redundant anyway:
class Child : public Base {
public:
Child() : Base(new int[10]) {
}
void print() {
for(int i = 0 ; i < 10 ; i++) {
// Make a[] protected in the parent
cout << a[i] << endl;
}
}
};
class Base
{
protected:
int *array;
...
}
If you would rather not make a protected in the parent, you can fix your code as follows (demo):
Child() : Base(array = new int[10]) {}
This is suboptimal, though, because a redundant member is kept in all instances of Child.
Base subobjects are initialised before class members, even if you write the initialisers in another order. So here:
Child(): array(new int[10]), Base(array)
the Base object is initialised first, using the uninitialised value of array.
Solutions include:
make Base::array accessible from Child, so it doesn't need its own copy;
move print into the base class, so that Child doesn't need to access array;
do something nasty like Child() : Base(array = new int[10]), if you really need a redundant copy of an inaccessible variable for some reason.
Make sure you've enabled compiler warnings; they should have caught this error.
It's because the base object is constructed first, and only then the child is constructed.
This means that your array is unintialised.
Put some tracing message at the begin and end of each of your consutructors, and you'll get a better understanding of how things work.
One solution would be to use std::array instead of raw pointer like the example below:
#include <iostream>
#include <array>
template<typename T, std::size_t N>
class Base
{
private:
std::array<T, N> const &array;
public:
Base(std::array<T, N> const &a) : array(a) { }
void print() const {
std::cout << "Printing array from Base class!" << std::endl;
for(auto i : array) std::cout << i << " ";
std::cout << std::endl;
}
};
template<typename T, std::size_t N>
class Child : public Base<T, N> {
private :
std::array<T, N> array;
public:
Child() : Base<T, N>(array) {
for(auto &i : array) i = 10;
}
void print() {
std::cout << "Printing array from Child class!" << std::endl;
for(auto i : array) std::cout << i << " ";
std::cout << std::endl;
}
};
auto main() -> int {
Child<int, 10> c;
c.print();
Base<int, 10> *b = &c;
b->print();
return 0;
}
Live Demo
Thus:
You wouldn't have to worry about releasing previously allocated memory.
Your Base class keeps a constant reference to the array object of the Child class. Thus, you save memory.

Template polymorphism

I've recently received a very good answer as how to overload specific class members by deriving classes.
The issue now is that one of the members is in fact templated with specializations either being BaseClass, DerivedClass or Derived2Class
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
template<class T>
class Queue
{
public:
Queue();
Queue(T*);
}
class Com
{
public:
virtual void setReady()
{
cout << "Com" << endl;
}
};
class DerivedCom : public Com
{
public:
void setReady()
{
cout << "DCom" << endl;
}
};
class Derived2Com : public Com
{
public:
void setReady()
{
cout << "D2Com" << endl;
}
};
class BaseClass
{
protected:
Com* com;
Queue<BaseClass>* queue;
public:
BaseClass(Com* c = new Com, Queue<BaseClass>* q = new Queue<BaseClass>) : com(c), queue(q)
{
}
void setReady()
{
com->setReady();
}
};
class DerivedClass : public BaseClass
{
public:
DerivedClass() : BaseClass(new DerivedCom, new Queue<DerivedClass>)
{
}
};
class Derived2Class : public BaseClass
{
public:
Derived2Class() : BaseClass(new Derived2Com, new Queue<Derived2Class>)
{}
};
int main()
{
BaseClass* base = new Derived2Class();
base->setReady();
return 0;
}
I can, without problem, "overload" simple classes like Com, DerivedCom and Derived2Com but the constructor signature of BaseClass won't fit to the type the deriving classes are trying to send it.
Instead of Queue<BaseClass>* queue; you should have Queue<BaseClass*> queue; or, even better, Queue<std::unique_ptr<BaseClass>> and initialize it only in the base constructor:
BaseClass(Com* c = new Com, Queue<BaseClass*> q = Queue<BaseClass*>()) : com(c), queue(q)
{
}
However having the BaseClass hold a collection of itself as a member is a code smell. I'd re-think that part.
The reason it's not working is that Queue<BaseClass> and Queue<DerivedClass> are completely different classes.
You should actually have Queue<BaseClass*>* queue = new Queue<BaseClass*>(); This declares a Queue pointer of type BaseClass pointer on the heap and allows you to use the pointer notation you mentioned above as queue->push(&BaseClass::setReady); and such...
Following an answer found elsewhere I changed the concept of class Queue to be template-less.