This question already has answers here:
Initializing an object to all zeroes
(12 answers)
Closed 9 years ago.
In C we set data to 0 with memset() function (Not only for the initialization).
My data could be changed by another method and I want to reuse it and then I want to set it to 0 before reusing it
Are there another way to set data to 0 in C++ other than memset()?
class MYClass : public NameSpace::ParentClass {
private:
struct mystruct data
public:
void method();
};
void MYClass::method() {
memset(&data, 0, sizeof(data)); // it's the C way. Are there another way in C++
}
In C++ you would invoke the constructor of an object, or the initialiser for primitive constructor-less objects.
Re-initialisation should actually happen very rarely (don’t reuse variables, create new ones! It makes the program flow clearer) – but when you need it you can just re-assign a new object:
data = mystruct();
It is ok to use memset on POD types, otherwise initialization must be done using constructor.
The C++ way of zeroing should look like the following:
struct mystruct
{
int i;
void Reset();
}
class MYClass : public NameSpace::ParentClass
{
private:
mystruct data
public:
void method();
};
void mystruct::Reset()
{
i = 0;
}
void MYClass::method()
{
data.Reset();
}
Related
This question already has answers here:
Ensuring compilation error while passing null pointer to a function
(3 answers)
Closed 3 months ago.
I am looking for a way to protect a class from receiving a NULL pointer at compiler time.
class B
{
// gives some API
}
class A
{
private:
B* ptrB_;
public:
A(B* ptrB)
{
// How can I prevent the class to be created with a null pointer?
ptrB_ = ptrB;
}
// multiple member function using: ptrB_
void A::Func1(void)
{
if(!ptrB_ )
rerturn; // I don't want to add it in every function.
...
return;
}
}
int main()
{
B tempB = NULL;
A tempA(&tempB);
}
How can I force user to always pass a pointer (not NULL) to A constructor?
Was looking at constexpr , but this forces to use static , and that's something I am trying to avoid.
To avoid the risk of NULL pointers, don't pass a pointer at all, instead use references (there are no 'null' references).
e.g.
A(B* ptrB) { ptrB_ = ptrB; } //instead of passing the address of an object
A(B& ptrB) { ptrB_ = &ptrB; } //take and store the address of the reference
This question already has answers here:
How to make an array with a dynamic size? General usage of dynamic arrays (maybe pointers too)? [closed]
(5 answers)
Closed 8 years ago.
In a project that I'm working on, I need to make a class that contains an array of pointers to other objects of the same class. I'm currently having trouble initializing this array.
Example:
class MrClass{
MrClass* otherInstances[];
public:
MrClass(MrClass* x[]){
otherInstances = x;
}
}
This array must be arbitrarily sized, since the number of instanced of the class to be passed is defined at compile time and it must be of pointers because multiple instances of the class must have access to the same objects.
Correct solution
Use std::vector<MrClass *> or std::array<MrClass *>. Or even better, std::vector<std::shared_ptr<MrClass>>
class MrClass{
std::vector<std::shared_ptr<MrClass>> otherInstances;
public:
MrClass(std::vector<std::shared_ptr<MrClass>> const & x)
: otherInstances(x)
{
}
}
Auxiliary solution
If you really need an array (and you really know, what you're doing), do the following:
class MrClass{
MrClass ** otherInstances;
int otherInstancesCount;
public:
MrClass(MrClass ** x, int count){
otherInstances = x;
otherInstancesCount = count;
}
}
Arbitrarily sized arrays are written std::vector in C++. So
you'd have:
class MrClass
{
std::vector<MrClass*> otherInstances;
public:
MrClass( std::vector<MrClass*> const& initialValues )
: otherInstances( initialValues )
{
}
};
I recently created my own scripting language. My code structures are heavily based on polymorphism. (I'm not really sure about how is this called. I've got a virtual function and then I derive the class and let the OS decide what to call on runtime):
class Statement
{
virtual void exec() = 0;
};
class PrintStmt : public Statement
{
void exec()
{
std::cout << expression->eval();
};
class AssignStmt : public Statement
{
void exec()
{
vm->bind_var(name, expression->eval())
};
Any ideas how I can rework this so it can be compiled by a pure C compiler?
I know this is general question and there is no single answer, but how would you do this?
Note: I already downloaded the python code as a reference, but it will take time until I figure out how it is working.
Statement would be a struct. In addition to its data members, you will need a function pointer e.g.
struct Statement
{
void(*exec)(Statement* this); // Function pointer
// Other members
};
You would then have different implementations of the functions per statement type and a function for manufacturing objects of the right type e.g.
static void printExec(struct Statement* this)
{
printf("%s", this->whatever);
}
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->exec = printExec;
return statement;
}
And you would invoke it like this:
statement->exec(statement);
The this pointer gives you access to the data members of the particular struct i.e. the instance whose exec method you invoked.
If you have lots of functions, consider using a vtable.
struct VTable
{
void(*exec)(Statement* this); // Function pointer
const char* (*stringValue)(Statement* this); // Function pointer
};
struct Statement
{
struct VTable* vtable;
// Other members
};
You build each a vtable for each kind of object only once
struct VTable printVTable =
{
printExec,
printStringValue
};
You create new objects thus:
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->vtable = &printVTable;
return statement;
}
and invoke the methods thus
statement->vtable->exec(statement);
The vtable method is more or less what C++ does behind the scenes.
The most straightforward way to convert this to C would probably be to use function pointers.
As #DrewNorman said, you will need to understand how vtables work, class layouts etc, and reimplement it (at least partially) in C. The example code below is very limited but gives you a hint of what to expect.
struct Statement {
void (*exec)(struct Statement* s);
};
struct PrintStmt {
struct Statement statement;
char* what;
};
void print_function(struct Statement* s) {
struct PrintStmt* p = (struct PrintStmt*)s;
printf(p->what);
}
// ...
struct PrintStmt p;
p.statement.exec = &print_function;
p.what = "Hello world";
p.statement.exec(p);
There are numerous C projects that use this kind of technique, GObject comes to my mind but it's far from the only one.
(Note: I'm used to C++ not really to C so this may not even be valid C but you get the idea anyway)
I'm trying to make a chess program, but I want to be able to implement different AIs in it. Thus I made a abstract AIgeneric class and the derived class AIrandom off of AIgeneric. Then in my chessAI interface, I create a list of the the AIs, and try to call their getNextMove function and run into a segfault. The code is as below:
class AIgeneric {
public:
virtual int getNextMove(int*, const int &) = 0;
}
class AIrandom : public AIgeneric {
public:
AIrandom();
virtual int getNextMove(int*, const int &);
}
class chessAI {
public:
chessAI();
~chessAI();
void setAI();
int getNextMove(int*, const int &);
private:
vector<AIgeneric*> AIlist;
vector<string> names;
int selectedAI;
};
chessAI::chessAI () {
AIrandom randomAI;
AIlist.push_back(&randomAI);
names.push_back("Random AI");
selectedAI = -1;
}
int chessAI::getNextMove(int * board, const int & color) {
return AIlist[selectedAI]->getNextMove(board, color); //segfault on this line
}
It'd be great if anyone could help me on this problem!
Edit: I do set selectedAI to 0 before calling getNextMove.
In this code:
chessAI::chessAI () {
AIrandom randomAI;
AIlist.push_back(&randomAI);
names.push_back("Random AI");
selectedAI = -1;
}
You store a pointer to a local variable into your vector. After the constructor returns that pointer is no longer valid.
Remember that all local variables are stored on the stack, and the stack is reused in other functions. So when you use the pointer in the vector, it now points to some other functions memory and not the one object you declared.
This can be solved in three ways:
Allocate the object on the heap:
AIlist.push_back(new AIRandom);
Not using pointers at all.
Use smart pointers, such as std::unique_ptr.
You call selectedAI = -1; and then AIlist[selectedAI]->.... What do you expect AIlist[-1] to be, other than undefined behavior?
I expect this is because AIlist[selectedAI] is out of bounds. You can confirm this by replacing it with AIlist.at(selectedAI). Keep in mind that this index is -1 immediately after the constructor...
Using C++ I built a Class that has many setter functions, as well as various functions that may be called in a row during runtime.
So I end up with code that looks like:
A* a = new A();
a->setA();
a->setB();
a->setC();
...
a->doA();
a->doB();
Not, that this is bad, but I don't like typing "a->" over and over again.
So I rewrote my class definitions to look like:
class A{
public:
A();
virtual ~A();
A* setA();
A* setB();
A* setC();
A* doA();
A* doB();
// other functions
private:
// vars
};
So then I could init my class like: (method 1)
A* a = new A();
a->setA()->setB()->setC();
...
a->doA()->doB();
(which I prefer as it is easier to write)
To give a more precise implementation of this you can see my SDL Sprite C++ Class I wrote at http://ken-soft.com/?p=234
Everything seems to work just fine. However, I would be interested in any feedback to this approach.
I have noticed One problem. If i init My class like: (method 2)
A a = A();
a.setA()->setB()->setC();
...
a.doA()->doB();
Then I have various memory issues and sometimes things don't work as they should (You can see this by changing how i init all Sprite objects in main.cpp of my Sprite Demo).
Is that normal? Or should the behavior be the same?
Edit the setters are primarily to make my life easier in initialization. My main question is way method 1 and method 2 behave different for me?
Edit: Here's an example getter and setter:
Sprite* Sprite::setSpeed(int i) {
speed = i;
return this;
}
int Sprite::getSpeed() {
return speed;
}
One note unrelated to your question, the statement A a = A(); probably isn't doing what you expect. In C++, objects aren't reference types that default to null, so this statement is almost never correct. You probably want just A a;
A a creates a new instance of A, but the = A() part invokes A's copy constructor with a temporary default constructed A. If you had done just A a; it would have just created a new instance of A using the default constructor.
If you don't explicitly implement your own copy constructor for a class, the compiler will create one for you. The compiler created copy constructor will just make a carbon copy of the other object's data; this means that if you have any pointers, it won't copy the data pointed to.
So, essentially, that line is creating a new instance of A, then constructing another temporary instance of A with the default constructor, then copying the temporary A to the new A, then destructing the temporary A. If the temporary A is acquiring resources in it's constructor and de-allocating them in it's destructor, you could run into issues where your object is trying to use data that has already been deallocated, which is undefined behavior.
Take this code for example:
struct A {
A() {
myData = new int;
std::cout << "Allocated int at " << myData << std::endl;
}
~A() {
delete myData;
std::cout << "Deallocated int at " << myData << std::endl;
}
int* myData;
};
A a = A();
cout << "a.myData points to " << a.myData << std::endl;
The output will look something like:
Allocated int at 0x9FB7128
Deallocated int at 0x9FB7128
a.myData points to 0x9FB7128
As you can see, a.myData is pointing to an address that has already been deallocated. If you attempt to use the data it points to, you could be accessing completely invalid data, or even the data of some other object that took it's place in memory. And then once your a goes out of scope, it will attempt to delete the data a second time, which will cause more problems.
What you have implemented there is called fluent interface. I have mostly encountered them in scripting languages, but there is no reason you can't use in C++.
If you really, really hate calling lots of set functions, one after the other, then you may enjoy the following code, For most people, this is way overkill for the 'problem' solved.
This code demonstrates how to create a set function that can accept set classes of any number in any order.
#include "stdafx.h"
#include <stdarg.h>
// Base class for all setter classes
class cSetterBase
{
public:
// the type of setter
int myType;
// a union capable of storing any kind of data that will be required
union data_t {
int i;
float f;
double d;
} myValue;
cSetterBase( int t ) : myType( t ) {}
};
// Base class for float valued setter functions
class cSetterFloatBase : public cSetterBase
{
public:
cSetterFloatBase( int t, float v ) :
cSetterBase( t )
{ myValue.f = v; }
};
// A couple of sample setter classes with float values
class cSetterA : public cSetterFloatBase
{
public:
cSetterA( float v ) :
cSetterFloatBase( 1, v )
{}
};
// A couple of sample setter classes with float values
class cSetterB : public cSetterFloatBase
{
public:
cSetterB( float v ) :
cSetterFloatBase( 2, v )
{}
};
// this is the class that actually does something useful
class cUseful
{
public:
// set attributes using any number of setter classes of any kind
void Set( int count, ... );
// the attributes to be set
float A, B;
};
// set attributes using any setter classes
void cUseful::Set( int count, ... )
{
va_list vl;
va_start( vl, count );
for( int kv=0; kv < count; kv++ ) {
cSetterBase s = va_arg( vl, cSetterBase );
cSetterBase * ps = &s;
switch( ps->myType ) {
case 1:
A = ((cSetterA*)ps)->myValue.f; break;
case 2:
B = ((cSetterB*)ps)->myValue.f; break;
}
}
va_end(vl);
}
int _tmain(int argc, _TCHAR* argv[])
{
cUseful U;
U.Set( 2, cSetterB( 47.5 ), cSetterA( 23 ) );
printf("A = %f B = %f\n",U.A, U.B );
return 0;
}
You may consider the ConstrOpt paradigm. I first heard about this when reading the XML-RPC C/C++ lib documentation here: http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#constropt
Basically the idea is similar to yours, but the "ConstrOpt" paradigm uses a subclass of the one you want to instantiate. This subclass is then instantiated on the stack with default options and then the relevant parameters are set with the "reference-chain" in the same way as you do.
The constructor of the real class then uses the constrOpt class as the only constructor parameter.
This is not the most efficient solution, but can help to get a clear and safe API design.