This question already has answers here:
Why is there no call to the constructor? [duplicate]
(3 answers)
Closed 9 years ago.
Of these two programs the second one works but the first one does not compile. How is that possible? The only difference is that in version two bar is a pointer and in version one it isnt.
Version one: (does not compile)
#include <iostream>
class Foo{
public:
void print(){
std::cout << "asdasd" << std::endl;
}
};
class Bar : public Foo{
};
int main(){
Bar bar();
bar.print();
}
And the second version:
#include <iostream>
class Foo{
public:
void print(){
std::cout << "asdasd" << std::endl;
}
};
class Bar : public Foo{
};
int main(){
Bar* bar = new Bar();
bar->print();
}
Bar bar();
is a declaration of a function.
Bar bar;
is your friend.
Related
This question already has answers here:
Derived template-class access to base-class member-data
(3 answers)
Why do I have to access template base class members through the this pointer?
(3 answers)
Closed 10 months ago.
With GCC, we can't access the member in the base class without writing this explicitly, but it works on MSVC, what is going on? Is it because of the CRTP?
#include <iostream>
template<class T>
struct Base {
protected:
T* a;
};
template<class U>
struct Derived : Base<Derived<U>> {
void print_a() {
std::cout << a << std::endl; // doesn't work on GCC
std::cout << this->a << std::endl; // works on GCC
}
};
int main() {
Derived<float> d;
d.print_a();
}
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.
This question already has answers here:
What's the difference between inline member function and normal member function?
(4 answers)
Closed 2 years ago.
i mean, this code:
class A
{
public:
void fun();
};
void A::fun()
{
cout << "fun() called";
}
is basically doing the same job as this:
class A
{
public:
void fun()
{
cout << "fun() called";
}
};
right? are there any differences between these codes, any particular reason to choose the one over the other?
Imagine two classes:
class A {
public:
A() { B b; }
};
class B {
public:
B() { A a; }
};
That code as written cannot compile, because no matter how you order those classes, one of them refers to something not defined. You can't forward-declare one class either, because it gets instantiated.
This code, however, compiles:
class A {
public:
A();
};
class B {
public:
B();
};
A::A() { B b; }
B::B() { A a; }
This question already has answers here:
What is object slicing?
(18 answers)
Closed 9 years ago.
I have the following piece of code (#includes and using namespace std omitted):
class A {
public:
void call(){callme();}
private:
virtual void callme() {cout << "I'm A" << endl;}
};
class B : public A {
private:
virtual void callme() {cout << "I'm B" << endl;}
};
class C : public B {
public:
virtual void callme(){ cout << "I'm C" << endl;}
};
int main(){
vector<A> stuff = {
A(), B(), C(),
};
stuff[0].call(); // output: I'm A
stuff[1].call(); // output: I'm A
stuff[2].call(); // output: I'm A
return 0;
}
As stated in the comments, the output of the above program is:
I'm A
I'm A
I'm A
However, I would like that C++ automatically recognizes the type with which the corresponding element was created. I.e. I would like that C++ outputs
I'm A
I'm B
I'm C
(That is, the compiler shall pick the proper subclass for me.)
Is this possible in this scenario (i.e. if all the elements come out of a vector)?
Member functions virtuality works only when you call them from pointer to the actual object, not from an object itself, because in your example objects were automatically statically upcasted to class A. Change your code to:
std::vector<std::unique_ptr<A>> stuff = {
std::unique_ptr<A>(new A()),
std::unique_ptr<A>(new B()),
std::unique_ptr<A>(new C()),
};
stuff[0]->call();
stuff[1]->call();
stuff[2]->call();
For C++ Polymorphism, you should use either pointer or reference. You could do like this
int main(){
vector<A*> stuff;
stuff.push_back(new A);
stuff.push_back(new B);
stuff.push_back(new C);
stuff[0]->call(); // output: I'm A
stuff[1]->call(); // output: I'm A
stuff[2]->call(); // output: I'm A
while (!stuff.empty()){
delete stuff.back();
stuff.pop_back();
}
return 0;
}
Reference: http://www.cplusplus.com/doc/tutorial/polymorphism/
This question already has answers here:
vector of objects
(5 answers)
Closed 8 years ago.
class classa {
public:
virtual void foo();
};
class classb : public classa {
public:
virtual void foo() override;
};
void classa::foo()
{
std::cout << "foo from a" << std::endl;
}
void classb::foo()
{
std::cout << "foo from b" << std::endl;
}
int main()
{
std::vector<classa> stuff;
classa a;
classb b;
stuff.push_back(a);
stuff.push_back(b);
stuff[0].foo();
stuff[1].foo();
return 0;
}
I expected the above code to return
foo from a
foo from b
but it returns both as foo from a.
I think this is because the vector stores classa but I am not sure.
How can I get classb:foo() to be called by b?
This happens because of object slicing, you'll need to keep a vector of pointers (preferably smart pointers).
I'm assuming stuff is defined as std::vector<classa> stuff;. When you do
stuff.push_back(b);
the object pushed into the vector is a slice of b - particulary the classa part. All other type info is lost. For this to work as expected, you'd need:
std::vector<classa*> stuff;
or similar. The way your code is now, you can't get it to work because stuff[1] is no longer a classb, but a classa.