473,396 Members | 1,891 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How can I use a non-trivial constructor with as little code duplicationas possible?

Hello, consider the following two classes (parent and child):

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <cstddef> /* NULL */

template <typename T>
class Singleton
{
public:
static T* get_instance()
{
if(!t)
{
t = new T;
}

return t;
}

private:
Singleton()
{
; /* Never reached. */
}

static T* t;
};

class int_singleton : public Singleton<int>
{
};

/* As with member functions of class templates, the definition must *
* be in the class header. When compilers properly support the export *
* keyword, definitions of member functions and static data members *
* can be moved to an implementation (.cpp) file. */
template <typename T>
T* Singleton<T>::t = NULL;

#endif /* #ifndef SINGLETON_HPP */

The int_singleton class is just an example, I will be using other
(user-defined classes) types in the "real application" (if I can make it
work).

If you look at Singleton::get_instance(), you see that when !t is true
it creates a new object of type T using the constructor that takes no
arguments. However, I need to use constructors that take several
arguments. How should I accomplish this so I get as little code
duplication as possible? I have several rather complex classes in my
program that, and there must be only one instance of each class at all
times, and I would like to use the base class Singleton as much as
possible. Maybe get_instance() should call a virtual create_object()
function when !t is true, a function I redefine in my subclasses?

Comments please, how should I solve this?

/ WP
Jul 22 '05 #1
5 1831
William Payne wrote:
Hello, consider the following two classes (parent and child):

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <cstddef> /* NULL */

template <typename T>
class Singleton
{
public:
static T* get_instance()
{
if(!t)
{
t = new T;
}

return t;
}

private:
Singleton()
{
; /* Never reached. */
}

static T* t;
};

class int_singleton : public Singleton<int>
{
};

/* As with member functions of class templates, the definition must *
* be in the class header. When compilers properly support the export *
* keyword, definitions of member functions and static data members *
* can be moved to an implementation (.cpp) file. */
template <typename T>
T* Singleton<T>::t = NULL;

#endif /* #ifndef SINGLETON_HPP */

The int_singleton class is just an example, I will be using other
(user-defined classes) types in the "real application" (if I can make it
work).

If you look at Singleton::get_instance(), you see that when !t is true
it creates a new object of type T using the constructor that takes no
arguments. However, I need to use constructors that take several
arguments. How should I accomplish this so I get as little code
duplication as possible? I have several rather complex classes in my
program that, and there must be only one instance of each class at all
times, and I would like to use the base class Singleton as much as
possible. Maybe get_instance() should call a virtual create_object()
function when !t is true, a function I redefine in my subclasses?

Comments please, how should I solve this?
My approach would be something like policy-based design of your
"Singleton" class. There should be construction policies from which
the developer can pick when it derives its specific singleton from
your template.

template<class T> struct DefaultConstructionPolicy
{
static T *get() { return new T(); }
};

template<class T, T t_def> struct ValueConstrutionPolicy
{
static T *get() { return new T(t_def); }
};

template<class T, template <class> ConstructionPolicy>
class Singleton
{
static T* get_instance()
{
return ConstructionPolicy<T>::get();
}
};

class int_singleton : public Singleton<int, IntZeroConstructionPolicy>
{
};

class int_42_singleton : public Singleton<int,
ValueConstructionPolicy<int,42>

{
};

[I didn't compile any of this, please take it as a hint only, not as
real code]

Victor
Jul 22 '05 #2
Victor Bazarov wrote:
William Payne wrote:
Hello, consider the following two classes (parent and child):

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <cstddef> /* NULL */

template <typename T>
class Singleton
{
public:
static T* get_instance()
{
if(!t)
{
t = new T;
}

return t;
}

private:
Singleton()
{
; /* Never reached. */
}

static T* t;
};

class int_singleton : public Singleton<int>
{
};

/* As with member functions of class templates, the definition must *
* be in the class header. When compilers properly support the export *
* keyword, definitions of member functions and static data members *
* can be moved to an implementation (.cpp) file. */
template <typename T>
T* Singleton<T>::t = NULL;

#endif /* #ifndef SINGLETON_HPP */

The int_singleton class is just an example, I will be using other
(user-defined classes) types in the "real application" (if I can make
it work).

If you look at Singleton::get_instance(), you see that when !t is true
it creates a new object of type T using the constructor that takes no
arguments. However, I need to use constructors that take several
arguments. How should I accomplish this so I get as little code
duplication as possible? I have several rather complex classes in my
program that, and there must be only one instance of each class at all
times, and I would like to use the base class Singleton as much as
possible. Maybe get_instance() should call a virtual create_object()
function when !t is true, a function I redefine in my subclasses?

Comments please, how should I solve this?

My approach would be something like policy-based design of your
"Singleton" class. There should be construction policies from which
the developer can pick when it derives its specific singleton from
your template.

template<class T> struct DefaultConstructionPolicy
{
static T *get() { return new T(); }
};

template<class T, T t_def> struct ValueConstrutionPolicy
{
static T *get() { return new T(t_def); }
};

template<class T, template <class> ConstructionPolicy>
class Singleton
{
static T* get_instance()
{
return ConstructionPolicy<T>::get();
}
};

class int_singleton : public Singleton<int, IntZeroConstructionPolicy>
{
};

class int_42_singleton : public Singleton<int,
ValueConstructionPolicy<int,42>
>

{
};

[I didn't compile any of this, please take it as a hint only, not as
real code]

Victor


Thanks for the quick reply, Victor! A bit more advanced than my attempt,
an attempt that ended in me noticing that a function can't be both
static and virtual. =(
I don't fully understand yet how I should use your design with my rather
complex classes. But I want to understand so I can use it!

/ WP
Jul 22 '05 #3
William Payne wrote:
Victor Bazarov wrote:
William Payne wrote:
Hello, consider the following two classes (parent and child):

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <cstddef> /* NULL */

template <typename T>
class Singleton
{
public:
static T* get_instance()
{
if(!t)
{
t = new T;
}

return t;
}

private:
Singleton()
{
; /* Never reached. */
}

static T* t;
};

class int_singleton : public Singleton<int>
{
};

/* As with member functions of class templates, the definition must *
* be in the class header. When compilers properly support the export *
* keyword, definitions of member functions and static data members *
* can be moved to an implementation (.cpp) file. */
template <typename T>
T* Singleton<T>::t = NULL;

#endif /* #ifndef SINGLETON_HPP */

The int_singleton class is just an example, I will be using other
(user-defined classes) types in the "real application" (if I can make
it work).

If you look at Singleton::get_instance(), you see that when !t is
true it creates a new object of type T using the constructor that
takes no arguments. However, I need to use constructors that take
several arguments. How should I accomplish this so I get as little
code duplication as possible? I have several rather complex classes
in my program that, and there must be only one instance of each class
at all times, and I would like to use the base class Singleton as
much as possible. Maybe get_instance() should call a virtual
create_object() function when !t is true, a function I redefine in my
subclasses?

Comments please, how should I solve this?


My approach would be something like policy-based design of your
"Singleton" class. There should be construction policies from which
the developer can pick when it derives its specific singleton from
your template.

template<class T> struct DefaultConstructionPolicy
{
static T *get() { return new T(); }
};

template<class T, T t_def> struct ValueConstrutionPolicy
{
static T *get() { return new T(t_def); }
};

template<class T, template <class> ConstructionPolicy>
class Singleton
{
static T* get_instance()
{
return ConstructionPolicy<T>::get();
}
};

class int_singleton : public Singleton<int, IntZeroConstructionPolicy>
{
};

class int_42_singleton : public Singleton<int,
ValueConstructionPolicy<int,42>
>

{
};

[I didn't compile any of this, please take it as a hint only, not as
real code]

Victor

Thanks for the quick reply, Victor! A bit more advanced than my attempt,
an attempt that ended in me noticing that a function can't be both
static and virtual. =(
I don't fully understand yet how I should use your design with my rather
complex classes. But I want to understand so I can use it!

/ WP


Hmm, I don't understand...doesn't one need some sort of base
ConstructionPolicy-class from which one derives? But if one has such a
class, one is confronted with the problem that a member function cannot
be both virtual and static. This code doesn't compile and that's because
the compiler sees a ValueConstructionPolicy when it wants a class named
ConstructionPolicy, right?

template <typename T>
class DefaultConstructionPolicy
{
public:
static T* create()
{
return new T;
}
};

template <typename T, T t_def>
class ValueConstructionPolicy
{
public:
static T* create()
{
return new T(t_def);
}
};

template <typename T, template <class> class ConstructionPolicy>
class Singleton
{
public:
static T* get_instance()
{
if(!t)
{
t = ConstructionPolicy<T>::create();
}

return t;
}

private:
Singleton()
{
; /* Never reached. */
}

static T* t;
};

class int_singleton : public Singleton<int, ValueConstructionPolicy<int,
4711> >
{
};

template <typename T>
T* Singleton<T, ConstructionPolicy>::t = NULL;

The compiler says:
singleton.hpp:60: error: type/value mismatch at argument 2 in template
parameter list for `template<class T, template<class> class
ConstructionPolicy> class Singleton'
singleton.hpp:60: error: expected a class template, got
`ValueConstructionPolicy<int, 4711>'
singleton.hpp:72: error: `ConstructionPolicy' was not declared in this scope
singleton.hpp:72: error: template argument 2 is invalid
singleton.hpp:72: error: template declaration of `T*t'

Line 60 is the opening { of the int_singleton class.
Line 72 is the definition of the static data member.

How should I solve this?

/ WP
Jul 22 '05 #4
"William Payne" <mi**************@student.liu.se> wrote...
[...]
Hmm, I don't understand...doesn't one need some sort of base
ConstructionPolicy-class from which one derives? But if one has such a
class, one is confronted with the problem that a member function cannot be
both virtual and static. This code doesn't compile and that's because the
compiler sees a ValueConstructionPolicy when it wants a class named
ConstructionPolicy, right?
Right. I thought a bit about it after I posted. Yes, I am still going
to hide behind the disclaimer: what I posted was for illustration only.
To make it work, you still need to research policy-based design and do
a bit of creative thinking. Get a copy of "Modern C++ Design" by Andrei
Alexandrescu.
[..]

Jul 22 '05 #5
Victor Bazarov wrote:
"William Payne" <mi**************@student.liu.se> wrote...
[...]
Hmm, I don't understand...doesn't one need some sort of base
ConstructionPolicy-class from which one derives? But if one has such a
class, one is confronted with the problem that a member function cannot be
both virtual and static. This code doesn't compile and that's because the
compiler sees a ValueConstructionPolicy when it wants a class named
ConstructionPolicy, right?

Right. I thought a bit about it after I posted. Yes, I am still going
to hide behind the disclaimer: what I posted was for illustration only.
To make it work, you still need to research policy-based design and do
a bit of creative thinking. Get a copy of "Modern C++ Design" by Andrei
Alexandrescu.

[..]


I don't see a way around the static-but-not-virtual-or-vice-versa-issue,
but maybe I can use a pointer to a (templated) function as the
construction policy? Ideas welcome!
I will check out the book when I go downtown friday, thanks!

/ WP
Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: lothar | last post by:
re: 4.2.1 Regular Expression Syntax http://docs.python.org/lib/re-syntax.html *?, +?, ?? Adding "?" after the qualifier makes it perform the match in non-greedy or minimal fashion; as few...
1
by: Markus Ernst | last post by:
Hi I wrote a function that "normalizes" strings for use in URLs in a UTF-8 encoded content administration application. After having removed the accents from latin characters I try to remove all...
4
by: bwmiller16 | last post by:
Guys - I'm doing a database consistency check for a client and I find that they're building unique indexes for performance/query reasons where they could be using non-unique indexes. Note...
32
by: Adrian Herscu | last post by:
Hi all, In which circumstances it is appropriate to declare methods as non-virtual? Thanx, Adrian.
0
by: Christopher Attard | last post by:
Hi, I need to create a dialog like the 'Add Counters' dialog box in perfmon. I'm using the System.Diagnostics namespace class in .NET and I've managed to do it. The problem arises when I'm...
14
by: Patrick Kowalzick | last post by:
Dear all, I have an existing piece of code with a struct with some PODs. struct A { int x; int y; };
13
by: Academic | last post by:
I have a MDI form, sometimes child forms and sometimes forms that are neither If I close the app the child forms closing and closed event happens followed by the Mdi form receiving the...
2
by: Lionel B | last post by:
I have a function which takes a functor argument. I which to call it for a functor which is actually a class member; this works fine, using the mem_fun_ref and bind1st functions (see listing 1...
6
by: Fabian Wein | last post by:
Hi, is there a way to call a const function from non const function? I have a non-const List GetList(); and want my
3
by: George2 | last post by:
Hello everyone, I am debugging MSDN code from, http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx here is my output, 1>main.cpp
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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...

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.