c++ Instance of class in same class, using constructor - c++

I have class A, is it possible to make sth like this? A(A(A()))? I mean creating some object in constructor and so on?
class A {
private:
A *a;
public:
A(){
printf("A()\n");
}
A( A * var){
printf("A(A)\n");
a = var;
}
};
int main() {
A x = A(A(A()));
return 0;
};
and this give me output A(), i mean why not A() A(A) A(A)? My A class represent a memory cell so A(1) is pointing to array[1] but A(A(1)) is sth like array[array[1]]. But i don't have idea how to implement this, only one object is created. (this A class is just an example of what I want to achieve)

Related

Manually calling constructor of base class outside initialization list

I have a Derived class whose constructor has to populate the fields of a struct that is passed as an argument to the constructor of the Base class. I want to be able to name the fields of the struct that I am populating, to keep my code future-proof (i.e.: resistant to addition and/or reordering of the members of MyStruct).
Note that struct MyStruct has default values, so it cannot be initialised with named fields directly in the initialization list (e.g.: Base({.a = a, .b = b}) does not work). Also, in my case, Base's copy constructor is deleted. Also, I am using C++ 11.
The solution I came up with uses the placement new operator to manually call the constructor of the Base class on the memory pointed to by this. To achieve this I also had to add a protected default constructor to my Base class. Are there any possible downsides to this approach and/or could anyone suggest a better method?
#include <iostream>
struct MyStruct
{
int a = 0;
int b = 1;
};
class Base
{
public:
Base(MyStruct str){
std::cout << "a: " << str.a << ", b: " << str.b << "\n";
}
Base(Base&&) = delete; // no copy constructor
protected:
Base(){ // dummy, does exactly nothing.
// it only exists to be called by
// the derived class's constructor
}
private:
int amember;
};
class Derived : public Base
{
public:
Derived(int a, int b)
{
MyStruct str;
str.a = a;
str.b = b;
new (this) Base(str);
}
private:
int anothermember;
};
int main()
{
MyStruct str;
str.a = 10;
str.b = 20;
Base b(str);
Derived d(10, 20);
return 0;
}
edit: added mention that Base cannot be copied, made explicit that Base::Base() does exactly nothing.
Use a helper function instead like
class Derived : public Base
{
public:
Derived(int a, int b) : Base(make_mystruct(a, b)), anothermember(some_value) {}
private:
int anothermember;
static MyStruct make_mystruct(int a, int b) { return MyStruct(a, b); }
};
I would just like to add that this could be a good opportunity to use IILE, Immediately Invoked Lambda Expression, if you for whatever reason don't want a named helper function:
class Derived : public Base
{
public:
Derived(int a, int b) : Base{[](){
MyStruct str;
str.a = a;
str.b = b;
return str; }()}
{}
};
The benefit is that you will not need to construct the class and it's members only once, since you do everything in the initialization list. If you in the future add non-trivial members to Base, you will be will not have to pay for double initialization.

How to handle objects that dont have a default constructor but are constructed in another constructor?

I have the following sample code
class ClassB {
public:
ClassB(int i); // No default constructor
}
class ClassA {
ClassB obj; //NOT a pointer
public
ClassA() {
//calculate someInt;
obj = ClassB(someInt); // doesnt work
}
}
How do I initialize obj?
The compiler complains about no appropriate default constructor available for obj
The best design solution for you would be to initialize member obj in the initialization list like this:
ClassA() : obj(someInt) { }
However, another option for you would be to declare the default constructor for ClassB like this:
ClassB() {}
or simply let the compiler create the one for you by using this:
ClassB() = default;
From C++ Standard this is:
defaulted default constructor: the compiler will define the implicit
default constructor even if other constructors are present.
If you go for a second option, then the following code would pass without the error:
#include <iostream>
class ClassB {
public:
ClassB() = default;
ClassB(int i);
};
class ClassA {
ClassB obj;
public:
ClassA() {
int someInt = 0;
obj = ClassB(someInt);
}
};
int main() {
return 0;
}
Check it out live
Conclusion
I would deeply recommend using the first option, the one with the initialization list because it is not needed to default construct objects before and then assigning to them. Also, this is the only option for objects that don't have an assignment operator.
UPDATE 1
One more way around this problem is using the std::shared_ptr<ClassB> obj in your ClassA as follows:
#include <iostream>
#include <memory>
class ClassB {
public:
ClassB(int i);
};
class ClassA {
std::shared_ptr<ClassB> obj;
public:
ClassA() {
int someInt = 0;
obj = std::make_shared<ClassB>(someInt);
}
};
int main() {
return 0;
}
UPDATE 2
One more possibility that came up to my mind is to calculate integer in a separate function and the just call it as part of the initialization list like in the following code:
#include <iostream>
class ClassB {
public:
ClassB(int i);
};
class ClassA {
ClassB obj;
public:
ClassA()
: obj(calculate())
{}
private:
int calculate() {
return 1;
}
};
int main() {
return 0;
}
Check it out live
You initialize members in the constructor initialization list. Like so:
ClassA() : obj(someInt) { }

Initialize a class object with the this pointer in C++

In C++, I want to initialize (or change) a class object using the result of another class' method. Can I use the this pointer? Is there a better way?
Dummy example:
class c_A {
public:
int a, b;
void import(void);
};
class c_B {
public:
c_A create(void);
};
void c_A::import(void) {
c_B B;
*this = B.create();
};
c_A c_B::create(void) {
c_A A;
A.a = A.b = 0;
return A;
};
There is no problem. The member function void import(void); is not a constant function.In this statement
*this = B.create();
there is used the default copy assignment operator.
Is there a better way?
A better way is not to use a member function and just use an assignment statement for objects of the class as for example
c_A c1 = { 10, 20 };
c1 = c_B().create();

Problem with object declaration/initialization as a private member on a different class

Sorry if this has been asked before, I can't seem to find anything. I'm not sure how to search for this.
I have something like this:
class A {
private:
int x;
int y;
public:
A(int, int);
}
class B {
private:
A a(3, 4); // Doesn't compile because of this line
public:
B();
}
The only way I could think to solve this was making a a pointer to A and then do a = new A(3, 4); inside B's constructor. But I don't want a to be a pointer.
What's the correct way to solve this?
You tag B's constructor with a "member initialization list". Instead of:
B::B() {
...
}
You do this:
B::B() : a(3, 4) {
...
}
Or if the constructor is defined in the header:
class B {
private:
A a;
public:
B() : a(3, 4) {
...
}
};
class B {
private:
A a;
public:
B() : a(3,4) {}
};
In a wider sense, the solution is to learn C++ by reading a book about it. Yes, that's snarky, but the point of tutorials is that they introduce concepts in a sensible order, and when they tell you about data members they will simultaneously tell you how to initialize them.
If what you want is for B.a to be initialized with the arguments 3 and 4, then you do that in B's constructor, e.g.,
class B {
private:
A a;
public:
B(): a(3, 4) {}
}

C++ referring to an object being constructed

In C++ I have a reference to an object that wants to point back to its owner, but I can't set the pointer during the containing class' construction because its not done constructing. So I'm trying to do something like this:
class A {
public:
A() : b(this) {}
private:
B b;
};
class B {
public:
B(A* _a) : a(_a) {}
private:
A* a;
};
Is there a way to ensure B always gets initialized with an A* without A holding a pointer to B?
Thanks
Try this:
class A;
class B {
public:
B(A *_a) : a(_a) {};
private:
A* a;
};
class A {
public:
A() : b(this) {};
private:
B b;
};
Since B is contained completely in A, it must be declared first. It needs a pointer to A, so you have to forward-declare A before you declare B.
This code compiles under more-or-less current versions of g++.
In C++ I have a reference to an object that wants to point back to its owner, but I can't set the pointer during the containing class' construction because its not done constructing.
You can store the pointer alright.
What you can't do is to try to get to the members/methods of A through the pointer in the constructor of B, since the parent instance might not be fully initialized at the point:
#include <iostream>
class Y;
class X
{
Y* y;
public:
X(Y* y);
};
class Y
{
X x;
int n;
public:
Y(): x(this), n(42) {}
int get_n() const { return n; }
};
X::X(Y* p): y(p)
{
//Now this is illegal:
//as it is, the n member has not been initialized yet for parent
//and hence get_n will return garbage
std::cout << p->get_n() << '\n';
}
int main()
{
Y y;
}
If you were to switch around the members in Y, so n would get initialized first, the constructor of X would print 42, but that is too fragile to depend on.