Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Questions : 33978185 , 32569833 didn't helped me.
By the way, in question 33978185 this error is considered as a bug, but since im using VS2017 i think it should be fixed by now.
Question 40181845 is using structs and i dont understand it quite well...
Question 38469597 says that i should make class B - friend class, is that the case here too?
I tried to search for more solutions but i havent got what i need.
Consinder my level of programming knowledge of object oriented c++ : Advanced> Normal > Begginer.
I am Normal.
I have class A, and class B:
class A
{
protected:
int q;
int w;
public:
A(int);
functionE();
functionR();
};
class B:public A
{
public:
functionT();
};
in main when i want to create a object of class B, I get error:
the default constructor "objectname" cannot be referenced -- its a deleted function.
From my knowledge of object oriented programming, when some members are protected, they can be accessed by the inherited class, and if inheritance is public, it can access public function.
I want my class B to have bonus functionT() and nothing else, but as i said, be able to access protected members of class.
One solution is to actually code functionT() in class A, which removes the need for class B, but I don't want that.
What should i do?
When you're trying to create an object of class B, you get an error as you didn't declare any constructor. B can't have a default constructor, as A doesn't have one either (when you declared A(int) as A constructor, you implicitly deleted the default constructor).
You can either create a default constructor for A, or default it by A() = default
or create a constructor for B, like so
B() : A(0) {}
B(int i) : A(i) {}
By providing the constructor A(int) the default constructor A() gets deleted. However, when creating an instance of class B it must call the constructor of its superclass A. The only way you provide is calling the default constructor, which doesn't exist anymore and thus your code does not compile.
In order for it to compile, you need to tell B how it is supposed to construct A. You can for example add this constructor to B: B(int a) : A(a) {}
Since you have a custom constructor for class A it needs to be called by the constructor of class B.
The generated 'empty' constructor of class B tries to call the 'empty' one of class A, which is no longer available. So you need to write a constructor for B as well.
class B : public A
{
public:
B() : A(0) {}
/* or */
B(int v) : A(v) {}
};
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm new into learning C++.
And what I've learned is that using global var is not a good practise.
And I don't wanna use static var, since they behave like "global" var as well, if I'm correct.
In the code below I want class B to get access to its "parents" member, is that possible?(see class B constructor)
Or how should I approach this, where I want to access var/members between classes?
Friends, seems not to be the way either.
class A {
public:
int number_I_want = 987;
A() {
B* classB = new B();
}
};
class B {
public:
int nr = 0;
B() {
nr = this->parent->numer_I_want; /// Here I wanna access the "parent" A's member with value 987
cout << nr * nr;
}
};
int main() {
A* classA = new A();
return 0;
}
Class A is The parent class so if the members/fields are not private . you can access them in class B. But the class B must Be the child of class A. You have to extend class b from A. And if you have parametrized constructor of parent class you must initialize classA constructor from class B
In C++, there is no parent\child relation for object. Sometimes it gets confusing with people coming from languages with object memory model (which are either VM-based or interpreters). Parent there is an object owning this one. C++ uses abstract memory model. If a class Bis inherited from other class A, class A is abase class of B. Base class and class members are subobjects of given class, meaning their storage is part of enclosing object's storage. Consecutively base class's members are subobjects too and are accessible as class members with consideration of access level and inheritance level (private, public, protected).
Enclosing object owns included ones and call to its destructor results in their destruction.
If you need actual parent\child relation , you have to implement it and pass a pointer (?) to parent into child's constructor, while it have to be able to register self within given parent.
Some C++ framework emulate object model by using metaprogramming technique, e.g. Qt Framework's QObject may have a parent and list of children.
Using pointer to >>this<< keyword when creating a "child" class worked for me.
class A {
public:
int nr;
A();
};
class B {
public:
B(A* classA) {
std::cout << "Written in class B, value from class A: "<< classA->nr;
};
};
A::A() {
nr = 77;
B* classB = new B(this);
delete classB;
}
int main() {
A* classA = new A();
delete classA;
return 0;
}
This question already has answers here:
call to pure virtual function from base class constructor
(8 answers)
Calling virtual functions inside constructors
(15 answers)
Closed 1 year ago.
I am trying to call an overriden function from the parent, and found out that it just crashes.
This is quite hard to describe, so here the minimal reproducible code:
#include <iostream>
class A
{
public:
A()
{
init1();
}
void init1()
{
printf("1");
init2();
printf("2");
}
virtual void init2() = 0;
};
class B : public A
{
public:
B()
: A()
{}
void init2() override
{
printf("hello");
}
};
int main()
{
B b;
return 0;
}
On MSVC 2019 it crashes, on http://cpp.sh/ it outputs "1" and then main() returns 0, but we never see "hello" or "2".
Why does it crash? What happens from a low level point of view? Is A trying to call its own init2()?
Is there a way of doing it, so I don't have to, in every derived class, add init2() in its constructor?
You can't call a derived class's overriden methods from within a base class constructor (or destructor). The derived class portion of the object doesn't exist yet.
So, to answer your questions:
yes A::A() is trying to call A::init2(), not B::init2(), and thus crashes from calling a pure virtual method.
There are ways (like via CRTP) for a base class constructor to call a derived class method, but doing so has limitations to it (ie, not being able to access any derived class data members since they still don't exist yet, only base class data members can be accessed). In your example, B::init2() doesn't access anyB data members, so it is possible for A::A() to call B::init2(), but in general you really need to wait for B to begin/finish constructing itself before you can safely call B::init2().
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When implementing an abstract class like this:
class Base
{
public:
virtual ~Base() = default;
virtual void foo() = 0;
};
Does this interface have to obey the rule of five i.e. do I have to add a copy constructor, copy assignment operator, move constructor and move assignment operator?
I'd figure that an instace of type Base can not be instantiated due to the pure virtual member function and thus providing default implementations for the other special member functions might serve no real purpose.
Is there any use-case/example that would require me to provide the other special member functions?
"abstract" is irrelevant here. A class needs its own copy constructor, copy assignment operator, etc. if it has data that won't be properly copied by the default versions. Full stop. The presence or absence of pure virtual functions does not change this. Your example doesn't have any data, so doesn't have an issue here.
Actually it is the contrary. I would consider deleting copying and assignment of a class that is supposed to be only an interface class to avoid slicing. Consider
class Base {
public:
virtual ~Base() {}
};
class D1 : public Base {
int i;
public:
~D1() override {}
};
class D2 : public Base {
int i;
double d;
public:
~D2() override {}
};
you could write something like this
vector<Base> vec;
D1 d;
D2 e;
vec.push_back(d);
vec.push_back(e);
. You would try to squeeze an object of size D2 into a much smaller object of type base. By deleting copy and assignment you do prevent the user or yourself doing that.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a class that creates instances of other classes, and when I call them, compiler gives me warning about order of the instances. Why does it matter? It does same job, regardless of the order.
E.g. I have this in my core class header file (core class handles game loop):
HUD hud;
World myWorld;
Like this they do all they need to. But compiler gives a warning:
'Core::myWorld' will be initialized after [-Wreorder]|
Then if I put myWorld instance above the hud instance, it doesn't give me warning anymore. I was just wondering, how on earth does it matter which order they are in?
Warning is since, in constructor initializer-list you initialize World before HUD, but actually members will be initialized in order they are declared in class.
Just litle example, where it can be worse:
class B
{
public:
B(int i) : value(i) {}
private:
int value;
};
class A
{
public:
A() : value(10), b(value)
{
}
private:
B b;
int value;
};
Here b will be initialized before value and so, something will be sended to b constructor, but not 10 as programmer want.
With
struct C
{
C() : p(std::make_unique<int>(42)), j(*p) {} // initialization doesn't use this order.
// but the order here:
int j;
std::unique_ptr<int> p;
};
you will dereference nullptr as j is initialized before p.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have 2 objects in my C++ program, both extending from the same parent class:
class A, and class B, both extending class base.
Is it possible create an object using class A, and then change it later in the program to class B?
Short answer, no. You cannot safely cast from A to B or B to A. You can safely cast to the base class since A IS_A base class and B IS_A base class but A and not a B and vice versa. There is no portable or safe way to do this. Whilst your compiler might let you do it and whilst it might appear to work the result of casting between to unrelated classes in this manner is undefined.
Incidentally, there is no reason why you can't add a cast constructor to allow A to be constructed from B and vice versa. That would be perfectly safe. You would just use the members of A to initialise the members of B and vice versa. Any members that are not common you'd have to deal with, probably be assigning them default values.
The following code works:
#include <iostream>
class Base {};
struct A : public Base {int a;};
struct B : public Base {int b;};
int main()
{
A *a = new A();
a->a = 1;
B *b = reinterpret_cast<B *>(a);
std::cout << b->b << std::endl;
return 0;
}
This is extremely ugly though and won't work properly if A and B don't have the exact same memory layout. This works if you need a and b to be the same object. If you don't mind them being different objects and residing in different places in memory then you can just write a constructor in B that receives an object of type A or a conversion operator.
This sounds like a classic example of the XY Problem and there probably exists a much more elegant solution to your actual problem.
As others have mentioned, no you cannot do this...technically. You can in fact achieve this effect through convert constructors and virtual functions.
If you write a convert constructor from A to B and B to A:
A::A(B convertFrom); // Convert from B to A
B::B(A convertFrom); // Convert from A to B
And you make the essential parts of each class virtual:
class base
{
virutal void baseClassFunction();
};
class A
{
virtual void baseClassFunction()
{
// Do things for A
}
};
Class B
{
virtual void baseClassFunction()
{
// Do things for B
}
}
Then you can simply make a pointer of type base which can hold a reference to either A or B.
Example bringing it all together;
int main()
{
base *ptr = new A();
bool needs_to_be_B;
...
// Program logic
ptr->baseClassFunction();
...
if(needs_to_be_B)
{
base *tmp = new B(*ptr);
delete ptr;
ptr = tmp;
delete tmp;
}
// ptr is now a B
ptr->baseClassFunction();
}
If you are confused look up virtual functions and convert constructors.