Two interdependent member functions with no default constructor - c++

I am sure that this question must be answered somewhere, but I cannot formulate the question...
My issue is that I have two objects (foo, bar), where bar needs to be initialized using foo instance. How to do it, when both objects are data members of another class (baz)?
I cannot initialize bar in baz constructor body as bar in this time must have been already initialized using default constructor that it is missing.
I cannot initialize bar in baz initializer list as foo has not been constructed in this time. Watch out as compiler does not care!
See the example:
#include <iostream>
#include <memory>
using namespace std;
class foo
{
public:
foo() {
cout << "foo constructor called." << endl;
}
private:
};
class bar
{
public:
bar(foo inFoo) : mFoo(inFoo) {
cout << "bar constructor called." << endl;
}
private:
foo mFoo;
};
class baz
{
public:
baz() : mBar(mFoo) {
cout << "baz constructor called." << endl;
} // ERROR: mFoo is not inizilized
private:
bar mBar;
foo mFoo;
};
int main()
{
baz Baz;
}
Only workaround that comes to my mind is using pointers in the baz class. Using of a pointer for bar data member allows me to postpone initialization until baz constructor body.
class baz
{
public:
baz() {
cout << "baz constructor called." << endl;
mBar = unique_ptr<bar>( new bar(mFoo) );
}
private:
unique_ptr<bar> mBar;
foo mFoo;
};
But is it possible to solve this problem without pointers?

Since mBar depends upon mFoo, just reorder the declarations:
private:
foo mFoo;
bar mBar;
and initialize mFoo first:
baz() : mFoo(), mBar(mFoo) {
// ...
}
Here's a demo.

Related

How to initialize C++ reference with different constructors based on condition?

The reference variable foo below is initialized with either an instance of Foo or its derived class Bar based on condition. Strangely enough, based on the output of the say() method, foo seems to be an instance of Foo rather than an instance of Bar — why?
#include <iostream>
class Foo {
public:
virtual void say() const {
std::cout << "Foo\n";
}
};
class Bar : public Foo {
public:
virtual void say() const {
std::cout << "Bar\n";
}
};
int main() {
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
}
If I annotate each constructor I can see that the Bar constructor is getting invoked when evaluating the ternary expression. If I annotate each destructor I see that Bar destructor is invoked before foo is initialized — this tells me that a temporary Bar object is created by the ternary operator, but is destroyed before initialization — why?
Compiled with (Apple LLVM version 9.0.0 (clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo {
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const {
std::cout << "Foo\n";
}
};
class Bar : public Foo {
public:
virtual void say() const {
std::cout << "Bar\n";
}
};
int main() {
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
}

Initialization of base class value for derived class

I want to create ab object of the base class Foo that initializes the variable value to something I decide, I then want to create an object of the derived class Bar and the variable value I decided earlier sticks with Foo that Bar inherits, like a constant one time initialization for the variable value.
Is there a way to do this without passing in the value every time I create the Bar object like with the Foo object or make the class value default to 5?
Example:
// Base class
class Foo {
private:
int value;
public:
Foo() {}
Foo(int value) : value(value) {}
int getValue() { return value; }
};
// Derived class
class Bar : public Foo {
private:
public:
Bar() {}
};
Foo foo(5);
foo.getValue() // 5
Bar bar;
bar.getValue() // this I also want to be 5 now
You can do this with static variables, either in class scope or method scope (with the latter having some differences, like lazy initialization, thread safe initialization, etc. Although, it does not make a big difference in your use case, but it is good to keep the latter in mind as an option). For example
#include <iostream>
using std::cout;
using std::endl;
// Base class
class Foo {
private:
static int value;
public:
Foo() {}
Foo(int value) {
Foo::value = value;
}
int getValue() { return value; }
};
int Foo::value = 0;
// Derived class
class Bar : public Foo {
private:
public:
Bar() {}
};
int main() {
Foo foo(5);
cout << foo.getValue() << endl;
Bar bar;
cout << bar.getValue() << endl;
}
I have just provided you with a solution you want. Keep in mind that this might not be the best way to achieve what you want. An object's construction parameters should ideally only affect the current object.

polymorphism with reference member variable

Can someone tell me what is wrong with my program below? I am using a reference member variable in a class for polymorphism. I am expecting the second cout to say "derived2" but it says "base";
#include <iostream>
// Example program
#include <iostream>
#include <string>
class base
{
public:
virtual void print(){ std::cout<<"base"<<std::endl;}
};
class derived: public base
{
public:
virtual void print(){ std::cout<<"derived"<<std::endl;}
};
class derived2: public base
{
virtual void print(){ std::cout<<"derived2"<<std::endl;}
};
class foo
{
public:
base & bar;
base boo;
derived foobar;
derived2 foobar2;
foo(): bar(boo){}
void newfoo(base & newfoo){ bar = newfoo; bar.print();}
};
int main()
{
foo test;
test.bar.print();
test.newfoo(test.foobar2);
}
Output:
base
base
As mentioned by others, you cannot reassign a reference.
Whenever you do something like bar = newfoo you are not resetting the reference. Instead you are invoking operator= for bar with newfoo as an argument.
Therefore, in your case you are slicing your objects and (let me say) copying its base part in bar.
A kind of reference-like tool to which you can reassign exists in the standard template library and it's called std::reference_wrapper.
It follows an example based on your code that uses it and has the expected behavior:
#include<functional>
#include <iostream>
#include <string>
class base
{
public:
virtual void print() { std::cout<<"base"<<std::endl;}
};
class derived: public base
{
public:
virtual void print(){ std::cout<<"derived"<<std::endl;}
};
class derived2: public base
{
virtual void print(){ std::cout<<"derived2"<<std::endl;}
};
class foo
{
public:
std::reference_wrapper<base> bar;
base boo;
derived foobar;
derived2 foobar2;
foo(): bar(boo){}
void newfoo(base & newfoo){ bar = newfoo; bar.get().print();}
};
int main()
{
foo test;
test.bar.get().print();
test.newfoo(test.foobar2);
}
In this case, operator= actually rebinds the reference to the given object. Anyway, as you can see, in this case you must invoke get to access the underlying reference.
Note: set aside the example above, your code isn't the typical use case for a std::reference_wrapper.
I mentioned it only for the sake of completeness.
You can't 'reassign' the reference. When assignment operator is used with the reference, it assigns the underlying value.
Thus, bar = newfoo; simply assigns foo of the base type to foobar, slicing it in the process.
You could have a different behavior if you'd substitute references with pointers, which can be re-assigned.
bar is a reference to boo, and boo is of type base whatever you assign to it.
Assignment can only change a variables value, not its type.
Polymorphism does not work with references. Try this:
#include <iostream>
// Example program
#include <iostream>
#include <string>
class base
{
public:
virtual void print(){ std::cout << "base" << std::endl; }
};
class derived : public base
{
public:
virtual void print(){ std::cout << "derived" << std::endl; }
};
class derived2 : public base
{
virtual void print(){ std::cout << "derived2" << std::endl; }
};
class foo
{
public:
base* bar;
foo(): bar(0) {}
void newfoo(base* newfoo){ bar = newfoo; bar->print(); }
};
int main() {
foo test;
test.newfoo(new derived2);
}

Difference between this->field and Class::field?

I'm wondering something in C++.
Admitting the following code:
int bar;
class Foo
{
public:
Foo();
private:
int bar;
};
Inside my class, is there any difference between this->bar and Foo::bar? Are there cases where one is invalid?
Inside class Foo (specifically) there is no difference between the two given that bar is not static.
Foo::bar is called the fully qualified name of the member bar, and this form is useful in scenarios where there may be several types in the hierarchy defining a member with the same name. For example, you would need to write Foo::bar here:
class Foo
{
public: Foo();
protected: int bar;
};
class Baz : public Foo
{
public: Baz();
protected: int bar;
void Test()
{
this->bar = 0; // Baz::bar
Foo::bar = 0; // the only way to refer to Foo::bar
}
};
They do the same thing members.
However, you wont be able to use this-> to distinguish members of the same name in the class hierarchy. You will need to use the ClassName:: version to do that.
For what I have learned fiddling around with C/C++, using the -> on something is mainly for a pointer object, and using :: is used for the classes that are part of a namespace or super class that is the general class of whatever you're including
It also allows you you to reference variable of another class (base class in most cases) with the same name. For me it's obvious from this example, hope it'll helps you.
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
int bar;
Base() : bar(1){}
};
class Derived : public Base {
public:
int bar;
Derived() : Base(), bar(2) {}
void Test() {
cout << "#1: " << bar << endl; // 2
cout << "#2: " << this->bar << endl; // 2
cout << "#3: " << Base::bar << endl; // 1
cout << "#4: " << this->Base::bar << endl; // 1
cout << "#5: " << this->Derived::bar << endl; // 2
}
};
int main()
{
Derived test;
test.Test();
}
This is because the real data stored in class is like this:
struct {
Base::bar = 1;
Derived::bar = 2; // The same as using bar
}

Is it possible to "inherit" a derived function from a base class function?

Firstly, let me apologise for the title, I honestly couldn't think how to word it better.
The example below should make my question a little clearer:
class Foo {
public:
Foo(int x);
};
class Bar : public Foo
{
public:
Bar(int y) : Foo(y);
};
Demonstrates code that would force the Bar constructor to call the Foo constructor with parameter Y. My question is, is there a similar method for inheriting a derived class function to call a base class function?
For example all calls to Bar.Func(); would also automatically call Foo.Func();?
class Foo {
public:
Foo(int x);
void DoIt();
};
class Bar : public Foo
{
public:
Bar(int y) : Foo(y);
void DoIt();
};
void Bar::DoIt()
{
Foo::DoIt();
}
If Foo is intended to be derived from and used polymorphicly, you should declare DoIt as virtual. In addition, you will also want a virtual base class destructor.
Automatically, no. You can use Base::member() to call it, though.
struct foo {
void frob() { std::cout << "foo::frob" << std::endl; }
};
struct bar : foo {
void frob() { foo::frob(); std::cout << "bar::frob" << std::endl; }
};
Any public function declared in Foo is also accessible via Bar (the same function will get called). If you may need to override the function in Bar to alter its behaviour, make it virtual.
This is the code you'll need if you want to 'inherit' the function statements for a function F() from its base. Declare F() virtual in Foo, implement some statements there. Then declare F() in Bar and make a call to Foo::F() at the beginning of the implementation of Bar::F():
class Foo {
public:
Foo(int i) { cout << "Foo(" << i << ") called." << endl; }
virtual void F() { cout << "foo::F() called." << endl; }
virtual ~Foo() {};
};
class Bar : public Foo {
public:
Bar(int i) : Foo(i) { cout << "Bar(" << i << ") called" << endl; }
void F() { Foo::F(); cout << "bar::F() called" << endl; }
};
int main(int argc, char** argv) {
Bar b(3);
b.F();
}
gives
Foo(3) called.
Bar(3) called
foo::F() called.
bar::F() called