I am currently trying to create a class that has a member object with a non-default constructor for an Arduino project. The object is a pointer so that I can construct when MyClass is constructed (MyObjClass *my_obj;)
// MyObjClass:
class MyObjClass(){
const int param;
public:
MyObjClass(const int param): param(param){ ... }
};
// MyClass:
class MyClass(){
MyObjClass *my_obj;
public:
MyClass::MyClass(const int param): my_obj(param){ ... }
};
It builds fine, but the value param in my_obj is rubbish (random value). Does it already initialize the object before the constructor call? My workaround is to use no const values but there must be a better way (the right way).
You are holding pointer to MyObjClass and try to init him with some int, the
right way will be my_obj(new MyObjClass(param)).
Also I would suggest to use smart pointers to avoid memory leaks.
Related
I use a library that only returns references to created objects Entity& Create(int id). In my class, I need to create one of these and store it.
I had thought to use class member std::reference_wrapper<Entity> MyClass::m_Entity but the problem is, I would like to create this object in a call to a method like MyClass::InitEntity() – so I run into a compile error "no default constructor available" because m_Entity is not initialised in my constructor.
Is there any way around this, other than to change my class design? Or is this a case where using pointers would make more sense?
Is MyClass in a valid state if it doesn't have a valid reference to an Entity? If it is, then you should use a pointer. The constructor initializes the pointer to nullptr, and the InitEntity function assigns it to the address of a valid Entity object.
class MyClass
{
public:
MyClass(): _entity(nullptr) {}
void InitEntity() { _entity = &Create(123); }
void doSomethingWithEntity()
{
if (_entity) ...
}
private:
Entity *_entity;
};
If MyClass isn't in a valid state without a valid reference to an Entity, then you can use a std::reference_wrapper<Entity> and initialize it in the constructor.
class MyClass
{
public:
MyClass(): _entity(Create(123)) {}
void doSomethingWithEntity()
{
...
}
private:
std::reference_wrapper<Entity> _entity;
};
Of course which one you go with depends on how MyClass is supposed to be used. Personally, the interface for std::reference_wrapper is a little awkward for me, so I'd use a pointer in the second case as well (while still ensuring that it's always not null).
Lately I have been having difficulties with constructors, and the different attempts from other questions and guides always have some form of segfault waiting for me at runtime (making compiling 80% of my time spent programming).
The following example shows the basic idea on what I am trying to accomplish:
struct Coord3{
float x, y, z;
Coord3() {x=0;y=0;z=0;};///Is this Correct?
};
struct Stat{
int Str,Dex,Int;
Stat(){Str=0;Dex=0;Int=0;};
};
struct Item{
Stat myStats;
Item(){...};
};
class SimpleChar{
public: ///to keep things simple for now
Coord3 pos;
Stat myStats;
int level;
float health;
Item inventory[20];
SimpleChar(){
level=0;
health=100;
}///What happens with 'pos', 'inventory' and 'myStats' in this class's constructor?
};
int main(){
SimpleChar myChar;
if(myChar.inventory[0].get()!=NULL){...}///this caused the most recent SEGFAULT as mentioned below. Why wouldn't this work?
}
With this example I have a bunch of simpler structs (similar to Coord3 and Stat). These structs are at the base level of my "engine", and are used accordingly to make higher level structs, then those are used to make the highest level structs (such as Item being item related information and SimpleChar having generic RPG character statistics, like an inventory and stats). The errors I get are so different according to the situation that it was difficult to keep track them all, but the most interesting one was a SEGFAULT on:
if(itemSet.inventory[a].get()!=NULL); ///Note: this is originally a shared_ptr AND was in a struct known as 'ItemSet', which held all item information
So basically what I ask is:
When are the default constructors invoked?
When the constructors are used, do they also invoke their member's constructors?
What would be the correct way to declare these members both in the classes and main()?
What is the correct way to create the constructor?
EDIT: The code has been spruced up for anyone that is way too obsessed with if the code is "valid by syntax" instead of actually answering the question.
EDIT 2: Since the SEGFAULTs are not created from constructor format then I ask if it is possible to get a SEGFAULT if an instance variable is too large in size? I mainly ask this because recently I have changed a class member to a pointer instead of an object and it worked fine.
when you declear a class like:
class foo{
public:
foo(){} // this is default constructor
};
But if you write:
class foo{};
The compiler will supply a default constructor for you. When you write:
class SimpleChar{
Coord3 pos; // default constructor of Coord3 will be called,
//if you need somrthing else do that in SimpleChar constructor;
Stat myStats; // same
int level;
float health;
Item inventory[20]; // an array will be created that can hold 20 item,
// constructor (default) will be called 20 times
};
Inside main() if you want to initialise an object with default constructor:
className instanceName;
is enough.
When You write:
SimpleChar myChar;
The following constructor is called:
SimpleChar(){
level=0;
health=100;
};
An additional point ; is mandetory after a class or struct definetion, which is absent in struct item{}
And default access specifier of struct is public but in class it is private, Which means you can not create object in main with default constructor.Edit:
"if an instance variable is too large in size" you may get a std::bad_alloc if it is being allocated dynamically in runtime but generally not a segfault. it happens when you access area you do not own.
1: When are the default constructors invoked?
Default constructors are called when:
You create an object without passing parameters
MyClass* myClass = new MyClass(); //<- this is you invoking it.
When you inherit from a class and dont specify a constructor in the initialization list for that base class.
class MyClass: public BaseClass
{
MyClass()
{
}
};
MyClass* myClass = new MyClass(); // <-- this will invoke the default constructor for "MyClass" and "BaseClass".
When you put an object in any stack and dont specify a constructor.
void methodA()
{
MyClass myClass; // <-- this will invoke the default constructor for "MyClass"
}
Same happens if you declare an object as a member of a class in its stack.
class MyClass
{
MyClass()
{
}
DifferentClass m_member;
};
If you dont specify a different constructor for m_member in the initialization list of MyClass, its default constructor will be used.
2: When the constructors are used, do they also invoke their member's
constructors?
As long as they are in the stack and not in the heap, and you dont specify otherwise in the initialization list of the class. Yes.
3: What would be the correct way to declare these members both in the
classes and main()?
It will depend on what you want, if you want to initialize them with its default constructor, you can just declare them as follow:
MyClass myClass; //<- this is fine.
4: What is the correct way to create the constructor?
A good practice is to ALWAYS initialize your members in the initialization list, for example:
struct Stat
{
int Str,Dex,Int;
Stat(): Str(0), Dex(0), Int(0)
{};
};
A simple example of how the default constructor works:
class base
{
int i;
public:
base()
{
i = 10;
cout << "in the constructor" << endl;
}
};
int main()
{
base a;// here is the point of doubt
getch();
}
Say I have an object of class baseclass:
// baseclass.h
class baseclass
{
baseclass() # default constructor, constructs baseclass object
}
And in the .cpp for baseclass:
// baseclass.cpp
baseclass::baseclass()
{
// member functions and variables
}
Now my goal is to have a derived class, and in the default constructor for the derived class, create an array of static size n baseclass objects. To try and clarify, an alternative way to think about this is to think about baseclass as playing cards, and I want to create an array (a deck) of those cards by calling the default constructor on the derived class. I decided to keep the scope of my question abstract however, so I will continue to use base/derived so others can more easily see how this could apply to them.
I am not sure the best way to set this up in an object oriented manner, so far I have something like this, but I am getting a segmentation fault. Here is how I have it set up:
// derivedclass.h (extending baseclass)
class derivedclass
{
// default constructor for derivedclass object
derivedclass();
// a pointer to an object of type baseclass
baseclass* bar;
// or should it be:
baseclass* bar[n] // where n is an integer
// or is there a better way to do it?
}
Lastly, since I said that a derivedclass object can have an array, I must make that true for the default constructor in the .cpp for derivedclass:
// derivedclass.cpp
derivedclass::derivedclass()
{
// so I need to initialize the member array
baseclass* bar = new baseclass[n] // where n is the size I want to initialize
// the array to
}
So would any of the situations I listed cause segmentation fault? What is the best way to create this array of object? Sorry if this is a nooby question, I am a student still learning a lot about memory allocation and pointers, normally deal with languages where I don't have to worry about this. Also, I tried to keep the question abstract for the benefit of others. Thanks in advance!
I am not sure why you need to use dynamic allocation at all here. I would rather do something like this, which would also save you some work in derivedclass's constructor:
struct baseclass
{
// Stuff...
};
struct derivedclass : baseclass
{
// Stuff...
baseclass objects[N];
};
In C++11 you should use std::array<> instead of a plain C-style array (std::array<> is a safe, zero-overhead wrapper of a C-style array):
// ...
#include <array>
struct derivedclass : baseclass
{
// Stuff...
std::array<baseclass, 10> objects;
};
// so I need to initialize the member array
baseclass *bar = new baseclass[n];
Except that with this, you don't initialize the member array, only a local variable that has the same name as the member variable, thus it shadows it (and for the very same reason, you're also leaking memory by loosing the pointer to the newly allocated array).
Why to use new at all? Why to derive deck from cards? Deck contains cards.
class Card
{
// ... whatever card does
};
class Deck
{
public:
static int const CountOfCards = 36;
typedef std::array<Card,CountOfCards> Cards;
Cards cards;
// etc. ... whatever deck does
};
i am pretty sure this is a simple question for a long time c++ user, this should be a pattern or the problem should be solved in any other way but given i am Python developer and a total novice with c++ i don't know how it's usually done.
Suppose that i have a class where i want to store a pointer to an object that can be of 1 of two different classes that respects an interface, for example:
class AllPlayers
{
public:
virtual void play();
};
class VlcPlayer: public AllPlayers
{
public:
virtual void play();
};
class Mplayer: public AllPlayers
{
public:
virtual void play();
};
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
VlcPlayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
else {
Mplayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
}
MyMediaPlayer test(0);
test.play();
First, i know this would not work and that it seems pretty normal why but how could i get this effect? i would like to have a member of a class for what i am going to use ever the same methods, implemented using a interface and i would like to avoid trying to cast to every of the derived classes every time i am going to use one of his methods.
C++ is value-based, i.e., if you create an object of a given type you really have an object of this type. This doesn't play nicely with dynamic polymorphism. To get dynamic polymorphism you use a pointer or a reference to the actual object. To also get the life-time straight you typicslly allocate the corresponding object on the stack (make sure your base class has a virtual destructor if you ever release an object of a derived type using a pointer to the base). With this, you should be all set: just call a virtual function of the base class through a pointer to rhe base: When you overridethe function in the derived class this is the function which is called.
If you write
AllPlayers m_player;
that is going to be an instance of AllPlayers and cannot be an instance of a class that derives from it.
You should instead use a pointer and allocate the class on the stack.
For example:
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
~MyMediaPLayer();
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
m_player = new VlcPlayer;
}
else {
m_player = new Mplayer;
}
}
MyMediaPlayer::~MyMediaPlayer()
{
if (0 != m_player) {
delete m_player;
m_player = 0;
}
}
As suggested by #xception use of unique_ptr may relieve you from having to write code to deallocate the instance.
As correctly pointed out by #DietmarKühl you should always declare a virtual destructor in a root class (a base class that does not itself derives from some other class) as is the case with AllPlayers.
class AllPlayers
{
public:
virtual ~AllPlayers();
virtual void play(); // note: this should probably be pure virtual.
};
The reason this will not work is colloquially known as Object Splicing. (Or, for those Harry Potter readers out there, Object Splinching)
Let's look at an example:
class Foo
{
public:
int bob;
float fred;
// Foo(const Foo& otherfoo); // implicit copy constructor
};
class Bar : public Foo
{
public:
double gabe; // gabe newell is fat
char steve; // steve jobs is thin
// Bar(const Bar& otherbar); // implicit copy constructor
};
int main()
{
Foo f;
Bar b;
f.bob = 10;
f.fred = 1.5;
b.bob = 15;
b.fred = 2.5;
b.gabe = 1.77245385091; // sqrt(pi)
b.steve = -4;
f = Foo(b);
return 0;
}
This is legal and valid. Problem is, the implicit copy constructor of Foo is called, and Foo's copy constructor knows nothing about what a Bar is. Only that it contains everything a Foo has, and some extra irrelevant crap. Because of this, only the Foo's data gets preserved; the data unique to the Bar gets spliced off.
It's important to note that this is DEFINED BEHAVIOR: it's doing EXACTLY WHAT YOU TELL IT TO. Casting between a subclass of a base class and a base class is implicit. Furthermore, the behavior of the copy constructor is implicit.
It's also important to note that, under the hood, C++ pointers and references work in the same way. It's perfectly sane to pass the Bar to Foo's copy constructor by reference, this pass by reference does not produce a copy of the object. It's the same as working with a pointer.
The actual splicing takes place as a direct result of the copy constructor biting off more than it can chew. It gets an object with more state than it expected, and its only choice is to ignore the extra state.
With python, this doesn't happen because everything is implicitly stored as a reference type. Since you only work with references (the objects themselves are abstracted away), you never have the opportunity to accidentally splice an object.
I'm confused with the this keyword in C++, I'm not sure that if I'm doing the right thing by passing this. Here is the piece of code that I'm struggling with:
ClassA::ClassA( ClassB &b) {
b.doSth(this);
// trying to call b's routine by passing a pointer to itself, should I use "this"?
}
ClassB::doSth(ClassA * a) {
//do sth
}
You're using it correctly. The this pointer points to the current object instance.
class helper
{
public:
void help(worker *pWorker) {
//TODO do something with pWorker . . .
}
void help2(worker& rWorker) {
//TODO do something with rWorker . . .
}
};
class worker
{
public:
void dowork() {
//this one takes a worker pointer so we can use the this pointer.
helper.help(this);
//to pass by reference, you need to dereference the this pointer.
helper.help2(*this);
}
helper helper;
};
Also, say you declare worker *pW = new worker(). If you call one of the methods (dowork) on the pW object, you will notice that the this pointer and pW have the exact same value (they are both the same address).
(haven't tested that to make sure it builds, but I think it should).
In C++, this is a keyword which is defined as "the pointer to the current object instance". So your code above is correct.
Depending on the inheritance/composition relationship between ClassA and ClassB, there are probably better ways to achieve what you are doing than by using the this pointer.
It's perfectly OK to pass 'this' or '*this' as you are doing.
Lifetime Dangers:
One point about the example you've supplied is that you're calling doSth from the constructor of ClassA. The object that's passed to doSth is possibly a partially constructed object:
class ClassC {
public:
ClassC ()
: m_c ()
{}
int m_c;
};
class ClassA : public ClassC {
public:
ClassA (ClassB & b)
: ClassC ()
, m_b ( b.doSth (this) ) // ClassC constructed
// ClassA members partially init.
{
b.doSth (this); // ClassA members initialized
}
// ...
int m_a;
};
class ClassD : public ClassA {
public:
ClassD(ClassB & b)
: ClassA (b) // Partially init
, m_d ()
{
// ClassC and ClassA constructed
// ClassD members initialized
}
int m_d;
};
There may be problems if doSth uses members that have not yet been initialized:
void ClassB::doSth (ClassA * a) {
int i = a->m_c; // OK m_c is initialized
int j = a->m_a; // Not OK, m_a not initialized when called
// from member initialization list.
int k = static_cast<ClassD*> (a).m_d; // Not OK
}
Using the dynamic type of the object:
Finally, any use of the dynamic type of the object (eg. virtual calls, dynamic_cast, typeid) will have different results on a partially constructed object than on a complete object (and in some case you can have undefined behaviour).
void ClassB::doSth (ClassA * a) {
if (ClassD * d = dynamic_cast<ClassD *> (a))
{
// Never true when called from ClassA::ClassA
}
}
In this case using this will pass a pointer to the caller class, which is A, to b.DoSth. It seems that you are doing it right. this keyword always points to the class instance that you are using it from.
this is a const pointer to its own object. this pointer is nonmodifiable.
ClassA::ClassA( ClassB &b) {
b.doSth(this);
// here 'this' refers to this object ie the instance of ClassA.
// When you pass 'this' to doSth function --> is equivalent to passing
// the instance of current object of ClassA.
//
}
If what you want is to make it the this as in thiscall, or, the actual very first parameter of any member functions (for g++), there is only one way: by the member access operators:
A* a = sth_that_give_you_an_A();
((B*)a)->doSth();
or in your case, if you want to pass the instance of class A to B::doSth.
((B*)this)->doSth();
Or, you may want to cast it to void* first to make your compiler happy.
If this is what you actually want, it is somehow the only way to do that.
However, an instance of class A may not also be an instance of class B. It is very rare that you want actually do this. You should find a proper way that allow you to down cast an instance of A to its subclass B with confidence.
Or otherwise, if you want to call B::doSth on the instance of B, it is just as normal as what you may do.
this is a pointer to the object instance, so what you are doing is correct.
Read this for more information.