473,467 Members | 1,342 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Member Objects based on templated classes


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
6 1507
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Sat | last post by:
Hi, I have a simplified version of a problem that I am facing (hope I haven't oversimplified it). This code doesn't work now and I want to find how I can make it work. Can I call the derived...
8
by: Ernst Murnleitner | last post by:
Hello Readers, Is there a way that only one class can construct a class A and its inherited classes A2, A3 etc.? I want to construct a class A (and the inherited classes A2, A3 etc.) from a...
9
by: Jon Wilson | last post by:
I have a class which needs to accumulate data. The way we get this data is by calling a member function which returns float on a number of different objects of different type (they are all the...
4
by: Lionel B | last post by:
Greetings, The following code: <code> template<typename T> class A { protected:
39
by: utab | last post by:
Dear all, Is there a clear distinction how to decide which functions to be members of a class and which not How is your attitude (Your general way from your experiences ...) "If the...
3
by: toton | last post by:
Hi, I want to specialize template member function of a template class . It is creating some syntax problem .... Can anyone say how to do it ? The class is something like this template<typename...
21
by: George Exarchakos | last post by:
Hi everyone, I'd like your help... Can we have a std::list<BASEwhere BASE be the base class of a class hierarchy? I want to add to this list objects that are inherited from BASE class but not...
2
by: mattjgalloway | last post by:
I'm having some problems with a templated member function of a templated class. Unfortunately I can't replicate it with a simple example so I know something odd must be going on!!! Basically it's...
3
by: Payne | last post by:
Hello, I'm having trouble figuring out how to best explain my problem but I hope I can make myself clear enough. Anyway, I'm doing an assignment for school and in this one we're supposed to write a...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.