This question already has answers here:
Why is there no call to the constructor? [duplicate]
(3 answers)
Most vexing parse
(1 answer)
Closed 9 years ago.
#include <iostream>
class Base
{
public:
int id;
};
int main()
{
Base b();
b.id = 1;
}
What is wrong with the object creation in the code above? What is the difference between Base b() and Base b?
This
Base b();
is parsed as a function declaration of a function called b() that returns a Base object. You need this:
Base b;
This will instantiate a Base object and call its default constructor. Note that this will not zero initialize base::id. You can fix this by providing a default constructor that does that:
class Base
{
public:
Base() : id(0) {}
int id;
};
and instantiate in the same way:
Base b;
The problem is that you are not instantiating an object, but rather declaring a function. This:
Base b(); // Function declaration! (not what you want)
Declares a function b() that returns an object of type Base and accepts no argument. Therefore, when you later try to access the member id, the compiler emits an error, because functions do not have members:
b.id = 1; // ERROR! b is a function, accessing member "id" makes no sense
If you want to create an instance of Base, instead, just remove the parentheses:
Base b; // Object instantiation! (what you want)
Notice that in C++11 you can use the uniform initialization syntax to create an instance of a class pretty much the way you were trying to do, but with curly braces instead of parentheses:
Base b{}; // Object instantiation! (what you want, in C++11)
Related
This question already has answers here:
What are the rules for calling the base class constructor?
(10 answers)
Closed 1 year ago.
#include <iostream>
using namespace std;
class A{
public:
A(){
cout << "Hello World";
}
};
class B:public A{
public:
B(){
cout << "World";
}
};
int main(){
B obj1;
return 0;
}
Why does this program print Hello WorldWorld, shouldn't it print World because I have created object of class B, so why is the constructor of A being called?
Conceptually, a base class becomes an unnamed sub object in the derived class, whose members are available in the same scope without extra qualification, and must be initialized.
You cannot avoid that initialization - which means a relevant constructor will be called or if it cannot be constructed then compiler will not allow you to inherit.
What you probably mean is whether the constructor should have overridden the base version, the simple answer is it cannot. If you want that effect - which will not work in constructors in a common sense way - you need to use virtual functions and overriding.
This question already has answers here:
C++ class member with constructor
(4 answers)
Avoid default constructor for member variable
(2 answers)
Explicitly initialize member which does not have a default constructor
(4 answers)
Closed 2 years ago.
I wish to have an object of one class contained inside a different class.
class A contained inside class B as in the simple example below.
The problem is that class A only has a parametrized constructor.
Is there another way to do declare the class A object in class B without having to use a pointer to class A ?
class A
{
public:
A(int var1, int var2);
private:
//...
};
class B
{
public:
B();
private:
A a; // Compiler error
A* a_ptr; // This will of course work fine. We can create a new A object with parameters any time using the a_ptr
};
A a; // Compiler error
except if the constructor of B explicitly calls the constructor of A with required arguments (e.g. B() : a(an_int, an_int) {...}), that requests a constructor without parameter or where all parameters have default value, but you do not have that constructor, only a constructor requiring 2 int
Is there another way to do declare the class A object in class B without having to use a pointer to class A ?
you do not declare but define / instantiate a new instance of A each time you instantiate a new instance of B
Note you can create later the instance of A without using a pointer as with a_ptr having for instance
std::vector<A> a;
and when you know the instance of A you need doing for instance
a.push_back(A(an-int, an-int));
but the fact you want only one instance is not visible in the definition of a (out of a welcome comment)
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
It might be a C++ beginner mistake but I'm really confused now by getting this compiler Error:
error: no matching function for call to 'B::B(A (*)())'
note: candidates are: B::B(A*)
I have written two class which look simplified like this:
//a very simple class A
class A
{
public:
A()
{
//do some stuff in Constructor
}
}
//another class, that stores a pointer to an object of A as a field
class B
{
private:
A* _a;
public:
//simply initialize the field in Constructor
B(A* a) : _a(a) { }
void doMagic()
{
//do something with _a
_a->xyz();
}
}
And what I am calling in my code is this:
A a();
B b(&a); //here the error appears
What I want is to create an object a and pass its pointer to object b. So that I have access to a in b's members.
It must be just something in the call of B b(&a); Perhaps you can find out what my Problem is very easily.
You're not creating an object of type A, instead, A a(); is a declaration of function, which takes no parameter, and the return type is A. So you're trying to pass a function pointer to the ctor of B, that's what compiler complains. You should change
A a();
to
A a;
A a();
defines a function with the name a that returns an object of type A.
You are passing that function to the constructor of type B.
Change the initialization of a to this so that you create an object of type a:
A a;
A a();
This is a function declaration. The rule is: Everything which can be a function declaration is a function declaration.
This could be either constructor call or function declaration, tho it will never become a constructor call.
Try this instead:
A a;
This question already has answers here:
How can I initialize base class member variables in derived class constructor?
(7 answers)
Closed 4 years ago.
I have a mistake I cannot understand when initializing member data in an inherited class with two different methods I thought they should be theoretically identical.
class gSolObject
{
public:
gSolObject();
virtual ~gSolObject(){}
bool isCollisionObject;
};
class gPlanetObject : public gSolObject
{
public:
gPlanetObject();
~gPlanetObject(){};
};
gSolObject::gSolObject():isCollisionObject(1)
{
}
gPlanetObject::gPlanetObject():gSolObject(),isCollisionObject(0)
{
}
I get an error class 'gPlanetObject' does not have any field named 'isCollisionObject'.
However when I put the initialization right into the constructor's brackts {..} instead:
gPlanetObject::gPlanetObject():gSolObject()
{
isCollisionObject=0;
}
It compiles fine. Why would that be?
EDIT: This also does not work
gPlanetObject::gPlanetObject():gSolObject(),gSolObject::isCollisionObject(0)
It writes 'expected class-name before '(' token'
You can't initialize member variables declared in base classes, because the base class constructor has already initialized them. All base constructors execute before member constructors.
You can reassign it. Or you can call a base class constructor that takes an argument and initializes its members with that value.
Edited : You can't call a method of a uninitialized object (here gSolObject) and that's why it works when you execute isCollisionObject(0) in the constructor. Furthermore, if you always set it to 0, then you should use default value in the gSolObject constructor.
This question already has answers here:
Accessing protected members in a derived class
(8 answers)
Closed 9 years ago.
Am a newbie to C++.
class A
{
public:
int i;
protected: //**--- [1]**
void set()
{
i=5;
cout<<i;
}
};
class B : public A
{
public:
void call()
{
A obj;
obj.set(); //**----[2]**
set(); //**---[3]**
}
};
int main()
{
B* b_obj = new B;
b_obj->call();
}
Why doesn't the code compiled if i try including [2] and not replacing [1] to public BUT it works if i compile including [3] alone?
Compiled error: error: ‘void A::set()’ is protected.
In short, My intention is to understand why base object cannot be called in derived class if the access specifier for the base class interface is set as protected.
Not sure if my answer is correct, but here goes:
set is protected in class A. This means no outside member can access set, but derived classes can.
When calling set() by itself inside B you are calling the function as a derived function from A inside your derived class B, meaning the compiler will accept this because the function is protected (accessible to derived classes.)
However when you define A obj, calling obj.set(), in relation to the obj instance, the call is external to the class, hence why the compiler gives error.
Hope that helps.
Pet is unrelated to A or B, so whether f.set() is allowed depends on the definition of Pet. By contrast, just set() works because it's protected in the base class, and hence accessible in derived classes.