By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,089 Members | 1,152 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,089 IT Pros & Developers. It's quick & easy.

Member Objects based on templated classes

P: n/a

I was presented a problem today where a class had member
variable that was an object of a templated class. The
class wanted to instantiate the object as a private member
variable and call a constructor other than the default
constructor. I couldn't figure out why it wasn't working
so I changed the member variable to a pointer to an object
instead and intialized it in the constructor and destroyed
in the destructor. It bothered me that I had to do this
work around so I generated the small app shown below to
see if I could duplicate the problem and I did. It seems
like you can't have an object that is based on a templated
class call anything other than the default constructor
when created on the stack. I looked in the Stroustrup
book see if there was a reference to this language feature
and couldn't find it. Am I missing something or is my
work around the only way to do this? Thanks!

Dan

P.S.
I compiled this using Visual C++ .Net. I haven't tried it
on 6.0 but it should work(I think...templates sometimes
give 6.0 problems but this is a very simple example)
************Example Follows**********************
// TestApp.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

//Templated Class
template <class T>
class DanTest
{
public:
//Default Constructor
DanTest():first(0),second(0){};

//Another Constructor
DanTest(int one, int two):first(one),second(two){};

private:
int first;
int second;

};

//Cleanup the Syntax with typedef
typedef DanTest<double> DanTestD;

//Class with a DanTestD member
class DanTestUser
{
public:

double value;
double value2;
static const int n_const_int = 5;

DanTestUser():value(0.0),value2(0.0){};

private:
//This works fine with the default constructor but
//the compiler throws a C2061 error when I try
//to user the alternate constructor.
//
DanTestD myDT(n_const_int,n_const_int);
};
int _tmain(int argc, _TCHAR* argv[])
{
DanTestUser x;
return 0;
}
Nov 16 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Dan Huantes wrote:

************Example Follows**********************

// TestApp.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

//Templated Class
template <class T>
class DanTest
{
public:
//Default Constructor
DanTest():first(0),second(0){};

//Another Constructor
DanTest(int one, int two):first(one),second(two){};

private:
int first;
int second;

};

//Cleanup the Syntax with typedef
typedef DanTest<double> DanTestD;

//Class with a DanTestD member
class DanTestUser
{
public:

double value;
double value2;
static const int n_const_int = 5;

DanTestUser():value(0.0),value2(0.0){};

private:
//This works fine with the default constructor but
//the compiler throws a C2061 error when I try
//to user the alternate constructor.
//
DanTestD myDT(n_const_int,n_const_int);


This is nonsensical. If you want to initialize a member variable
(with only one limited exception), the place to do it is in the
constructor (preferably, the member initialization list).

Your constructor should read:
DanTestUser() : value(0.0), value2(0.0),
myDT(n_const_int, n_const_int) {}

--
Craig Powers
MVP - Visual C++
Nov 16 '05 #2

P: n/a
That is a terrible mix of Java, C++ and something else :-)

See fixed version below.

Vladimir.

//Templated Class
template <class T>
class DanTest
{
public:
//Default Constructor
DanTest():first(0),second(0){};
//Another Constructor
DanTest(int one, int two):first(one),second(two){};
private:
int first;
int second;
};

//Cleanup the Syntax with typedef
typedef DanTest<double> DanTestD;

//Class with a DanTestD member
class DanTestUser
{
public:

double value;
double value2;
static const int n_const_int;

DanTestUser():value(0.0),value2(0.0), myDT(n_const_int, n_const_int) {};

private:
//This works fine with the default constructor but
//the compiler throws a C2061 error when I try
//to user the alternate constructor.
//
DanTestD myDT;
};

const int DanTestUser::n_const_int=5;

int main(int argc, char* argv[])
{
DanTestUser x;
return 0;
}
Nov 16 '05 #3

P: n/a
Thanks! I could have sworn I could do this before but I
checked Visual C++ 6.0 and the compiler complained there
too. I must be losing it. I also tend to lean toward
pointers when it comes to members that are objects. In
that case I would initialize them in the constructor
using 'new'. By the way... what is the "limited
exception"? The only place I can think of is with a COM
CoClass using HRESULT FinalConstruct().

Also... You indicated "preferably the member
initialization list". What's the advantage over just
doing it within the constructor body? Just curious!

Thanks Again!

Dan

This is nonsensical. If you want to initialize a member variable(with only one limited exception), the place to do it is in theconstructor (preferably, the member initialization list).

Your constructor should read:
DanTestUser() : value(0.0), value2(0.0),
myDT(n_const_int, n_const_int) {}

--
Craig Powers
MVP - Visual C++
.

Nov 16 '05 #4

P: n/a
Dan Huantes wrote:
Thanks! I could have sworn I could do this before but I
checked Visual C++ 6.0 and the compiler complained there
too. I must be losing it. I also tend to lean toward
pointers when it comes to members that are objects.
A usually useful rule: if a class has virtual functions, store a pointer
(or reference) as the member, and create it using new. If a class doesn't
have virtual functions (which generally behaves it behaves like a "value
type"), then store the member directly rather than a pointer. Of course,
there will always be exceptions to this rule.
In
that case I would initialize them in the constructor
using 'new'. By the way... what is the "limited
exception"? The only place I can think of is with a COM
CoClass using HRESULT FinalConstruct().
The exception would be places where you can't do it in the member
initializer - e.g. where it must be done in another member function and not
the constructor.

Also... You indicated "preferably the member
initialization list". What's the advantage over just
doing it within the constructor body? Just curious!


All members are initialized before the constructor body is entered. If a
member if of class type, then some constructor for that member will run
before the constructor body is entered. In the body, you'll use assignment
to define the value of the member, which generally results in at least one
more constructor call followed by a call to the assignment operator. For
simple members like int's there's no significant difference (and indeed, in
most cases, no difference even at the machine language level), but for
members of class type, using the member-initializer list can be
significantly more efficient.

Further, if you have a member of a const-qualified type, or a member that's
a reference type, or a member of class type with no default constructor,
then the member initializer is the only place where you can initialize it.
It's best to just always use the member initializer list unless there's a
really good reason not to.

-cd
Nov 16 '05 #5

P: n/a
Dan Huantes wrote:

Thanks! I could have sworn I could do this before but I
checked Visual C++ 6.0 and the compiler complained there
too. I must be losing it. I also tend to lean toward
pointers when it comes to members that are objects. In
that case I would initialize them in the constructor
using 'new'. By the way... what is the "limited
exception"? The only place I can think of is with a COM
CoClass using HRESULT FinalConstruct().


The one I had in mind was the one that you had already used in the
class - initialization of a static const integral type at the point of
declaration, but obviously yours and Carl's work as well (but aren't
quite the sort of initialization I was thinking of when I wrote the
sentence).

--
Craig Powers
MVP - Visual C++
Nov 16 '05 #6

P: n/a
Excellent responses. Thank you! Happy coding!

Dan
-----Original Message-----
Dan Huantes wrote:
Thanks! I could have sworn I could do this before but I
checked Visual C++ 6.0 and the compiler complained there
too. I must be losing it. I also tend to lean toward
pointers when it comes to members that are objects.
A usually useful rule: if a class has virtual functions,

store a pointer(or reference) as the member, and create it using new. If a class doesn'thave virtual functions (which generally behaves it behaves like a "valuetype"), then store the member directly rather than a pointer. Of course,there will always be exceptions to this rule.
In
that case I would initialize them in the constructor
using 'new'. By the way... what is the "limited
exception"? The only place I can think of is with a COM
CoClass using HRESULT FinalConstruct().
The exception would be places where you can't do it in

the memberinitializer - e.g. where it must be done in another member function and notthe constructor.

Also... You indicated "preferably the member
initialization list". What's the advantage over just
doing it within the constructor body? Just curious!
All members are initialized before the constructor body

is entered. If amember if of class type, then some constructor for that member will runbefore the constructor body is entered. In the body, you'll use assignmentto define the value of the member, which generally results in at least onemore constructor call followed by a call to the assignment operator. Forsimple members like int's there's no significant difference (and indeed, inmost cases, no difference even at the machine language level), but formembers of class type, using the member-initializer list can besignificantly more efficient.

Further, if you have a member of a const-qualified type, or a member that'sa reference type, or a member of class type with no default constructor,then the member initializer is the only place where you can initialize it.It's best to just always use the member initializer list unless there's areally good reason not to.

-cd
.

Nov 16 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.