How to initialise aggregate member?

F

Frederick Gotham

How do we initialise an aggregate member object of a class? The following
won't compile for me:

struct MyStruct {
int i;
double d;
};

class MyClass {
private:
MyStruct const obj;

public:
MyClass() : obj( {5,45.67} ) {}
};

int main()
{
MyClass obj;
}
 
T

Thomas Tutone

Frederick said:
How do we initialise an aggregate member object of a class? The following
won't compile for me:
struct MyStruct {
int i;
double d;

Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}
};

class MyClass {
private:
MyStruct const obj;

public:
MyClass() : obj( {5,45.67} ) {}

switch it to:

MyClass() : obj(MyStuct(5, 45.67)) {}
};

int main()
{
MyClass obj;
}

And don't worry about the extra MyStruct that gets constructed and
copied - your compiler ought to optimize that right out of there - or
else switch to a better compiler.

Best regards,

Tom
 
M

Marcus Kwok

Thomas Tutone said:
Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}


switch it to:

MyClass() : obj(MyStuct(5, 45.67)) {}

Even that is not necessary; you can just have:

MyClass() : obj(5, 45.67) { }
 
E

erazerhead

struct MyStruct {
Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}


switch it to:

MyClass() : obj(MyStuct(5, 45.67)) {}


And don't worry about the extra MyStruct that gets constructed and
copied - your compiler ought to optimize that right out of there

why copy it at all?

MyClass () : obj (5, 45.67) {}
 
V

Victor Bazarov

Frederick said:
How do we initialise an aggregate member object of a class? The
following won't compile for me:

struct MyStruct {
int i;
double d;
};

class MyClass {
private:
MyStruct const obj;

public:
MyClass() : obj( {5,45.67} ) {}
};

int main()
{
MyClass obj;
}

Yes. There is no "aggregate literal" in C++. You will have to resort
to a "constructor function", like this

MyStruct makeMyStruct(int i, double d) {
MyStruct m = { i, d };
return m;
}
...
MyClass() : obj(makeMyStruct(5, 45.67)) {}

V
 
F

Frederick Gotham

Thomas Tutone posted:
Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}


Yes, I'm aware that that is possible. I don't want to resort to it though.
"MyStruct" should be a very simple aggregate POD which simply contains two
members.

switch it to:

MyClass() : obj(MyStuct(5, 45.67)) {}


Why the redundant nameless object? You could simply have written:

MyClass : obj(5,45.57) {}

And don't worry about the extra MyStruct that gets constructed and
copied - your compiler ought to optimize that right out of there - or
else switch to a better compiler.


Better yet, I'll omit it myself.
 
V

Victor Bazarov

Thomas said:
Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}

But in this case 'MyStruct' is not an aggregate any longer.
switch it to:

MyClass() : obj(MyStuct(5, 45.67)) {}

If you decide to break the "aggregateness" of MyClass, then there is no
need for the extra type name. Just do

MyClass() : obj(5, 45.67) {}
And don't worry about the extra MyStruct that gets constructed and

There is no need for it. Once it's removed, nothing to worry about.
copied - your compiler ought to optimize that right out of there - or
else switch to a better compiler.

V
 
K

Kaz Kylheku

Thomas said:
Give the compiler a little help:

MyStruct(int ii, double dd) : i(ii), d(dd) {}

Good luck with this approach if the struct in question is declared in
some platform or third-party header that you cannot touch.
 
F

Frederick Gotham

Frederick Gotham posted:
How do we initialise an aggregate member object of a class?


Similarly, how do we do it with "new"?

struct MyStruct {
int i;
double d;
};

int main()
{
MyStruct const *const p = new MyStruct const( {5,67.3} );
/* Compile ERROR */
}
 
F

Frederick Gotham

Victor Bazarov posted:
Yes. There is no "aggregate literal" in C++. You will have to resort
to a "constructor function", like this

MyStruct makeMyStruct(int i, double d) {
MyStruct m = { i, d };
return m;
}
...
MyClass() : obj(makeMyStruct(5, 45.67)) {}


Please excuse me while I knock down the door of comp.std.c++.
 
C

Clark S. Cox III

How do we initialise an aggregate member object of a class? The
following won't compile for me:

struct MyStruct {
int i;
double d;
};

class MyClass {
private:
MyStruct const obj;

public:
MyClass() : obj( {5,45.67} ) {}
};

int main()
{
MyClass obj;
}


If MyStruct must remain an aggregate (i.e. you can't add a constructor
as mentioned in other responses), you're basically limited to writing a
simple function to do your work for you:

MyStruct makeMyStruct(int i, double d)
{
MyStruct result = {i,d};
return result;
}

....
MyClass() : obj(makeMyStruct(5,45.67)) {}
 
J

John Carson

Frederick Gotham said:
Thomas Tutone posted:



Yes, I'm aware that that is possible. I don't want to resort to it
though. "MyStruct" should be a very simple aggregate POD which simply
contains two members.

I might ask why, but...you could do this:

MyClass()
{
obj.i = 5;
obj.d = 45.67;
}

Alternative, if you want to use an initialisation list, you could do this:

struct MyStruct {
int i;
double d;
};

class MyClass {
private:
MyStruct obj;
static MyStruct ms;

public:
MyClass() : obj(ms) { }

};

MyStruct MyClass::ms = {5, 45.67};

int main()
{
MyClass obj;
return 0;
}

i.e., you manually initialise a static instance of the struct and then you
can use the static variable to initialise your member variable for every
object of the class that you create.
 
F

Frederick Gotham

John Carson posted:
I might ask why, but...you could do this:

MyClass()
{
obj.i = 5;
obj.d = 45.67;
}


Can't be done with a const object.

Alternative, if you want to use an initialisation list, you could do this:

struct MyStruct {
int i;
double d;
};

class MyClass {
private:
MyStruct obj;
static MyStruct ms;

public:
MyClass() : obj(ms) { }

};

MyStruct MyClass::ms = {5, 45.67};

int main()
{
MyClass obj;
return 0;
}


What if the constructor's parameters should determine the values?

MyClass(int argi, double argd) : obj({argi + 7, argd / 2}) {}
 
J

John Carson

Frederick Gotham said:
John Carson posted:



Can't be done with a const object.

Right. While playing with your code, I deleted the const qualifier to get
rid of warnings about the assignment operator.
What if the constructor's parameters should determine the values?

MyClass(int argi, double argd) : obj({argi + 7, argd / 2}) {}


Then I think you need Victor's "constructor function".

If you were really desperate to use the static struct technique, then you
could create an extra member variable for the sole purpose of having its
constructor set the static struct object's values to the desired levels.
This would need to appear before the MyStruct object within MyClass. I
recommend against it, however, since it is ugly and increases the size of
your class.

struct MyStruct {
int i;
double d;
};

class MyClass
{
private:
struct Auxiliary
{
Auxiliary()
{
ms.i = 5;
ms.d = 45.67;
}
Auxiliary(int argi, double argd)
{
ms.i = argi + 7;
ms.d = argd/2;
}
};
Auxiliary a;
const MyStruct obj;
static MyStruct ms;
public:
MyClass() : obj(ms)
{}
MyClass(int argi, double argd) : a(argi, argd), obj(ms)
{}
};

MyStruct MyClass::ms;

int main()
{
MyClass obj1, obj2(20, 5);
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top