PDA

View Full Version : problems in instantiation/declaration of struct in c++



monkeyking
July 21st, 2009, 11:07 AM
I'm puzzled by why the code snippet doesnt work,
can anyone clarify

thanks



#include <iostream>
#include <cstring>

struct data{
char *name;
int number;
};


int main(int argc, char** argv){
const char* ns = "John";
int age = 27;
data sl = {strdup(ns),age};//woks

//below doestnt work
data ls;
ls = {strdup(ns),age};
}

dwhitney67
July 21st, 2009, 11:21 AM
Your second attempt makes no sense to me, much less to the compiler. It should yield a syntax error.

Try the same in C and I bet the same thing will occur.

Sockerdrickan
July 21st, 2009, 12:01 PM
Yes why would the second work? That syntax is only available when instantiating.

edit: perhaps check out C++0x?


#include <cstring>

struct data {
const char *name;
int number;
};

int main() {
const char* ns{"John"};
int age{27};
data s1;
s1={strdup(ns),age};
} seems like a waste to do it like that though

fr4nko
July 21st, 2009, 12:58 PM
I'm puzzled by why the code snippet doesnt work,
can anyone clarify

thanks



#include <iostream>
#include <cstring>

struct data{
char *name;
int number;
};


int main(int argc, char** argv){
const char* ns = "John";
int age = 27;
data sl = {strdup(ns),age};//woks

//below doestnt work
data ls;
ls = {strdup(ns),age};
}



The second attempt does not work because


it does define a instance of the class data with the default constructor
it does perform an assignment but you didn't define the assignement operator

so the following code should work:


struct data{
char *name;
int number;

data & operator= (const data &rhv) {
this->name = rhv.name;
this->number = rhv.number;
return *this;
};

data() : name(NULL), number(0) { };
};
because we defined a default constructor and an assignment operator that does something meaningful.

Francesco

dribeas
July 21st, 2009, 08:38 PM
The tricky part is that while what you read seem similar in both cases (where it works and where it does not), they are different.

In the first case, what seems like an assignment is really an initialization of an aggregate type. In the case you are instantiating the struct and later trying to assign to it. A workaround is adding a cast operation that will force the compiler into creating a temporary of the type initialized with the initializer-list.



data sl = { 0, 0 }; // aggregate initialization
data ls; // variable declaration
//ls = { 0, 0 }; // fails: assignment cannot take an initializer-list
ls = (data) { 0, 0 }; // work-around


If you are learning C++, I would recommend that you use the standard library as much as possible (i.e. use std::string instead of char* to hold strings)

@fr4nko proposes that you define constructors for your struct (which in C++ is just a class with default public accessibility). That is a good recommendation.

On the other hand, to be precise I must comment on the two items he lists:

'It defines an instance of the class with default constructor'

Initialization in C++ is tricky to maintain compatibility with C and top-notch performance in the code. In particular, in this example as the struct/class is actually a POD, the implicit (compiler generated) default (parameter-less) constructor will not be called. Had there been a user-defined default constructor it would have been called. The list of possible cases is long, so I won't extend it here.

'It does perform an assignment but you didn't define the assignement operator'

Unless you require specific semantics you do not need to define the assignment operator. The compiler will generate one for you. Assignment is one of the three magic methods that the compiler will provide for you. In particular, for POD types, the compiler generated assignment operator does the equivalent of a memcpy (bit-wise copy of the contents of the POD).

fr4nko
July 21st, 2009, 10:20 PM
Thank you for the precisions and your remarks about POD. I perfectly agree with everything you said :-)

Francesco

monkeyking
July 22nd, 2009, 05:39 PM
thanks people