473,378 Members | 1,544 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,378 software developers and data experts.

detect private/public constructor at compile time?

fschaper
hello,

is it possible to determine if an constructor is public or private at compile time using template metaprogramming/SFINAE?

kind regards and thanks in advance for the help,

florian
Oct 31 '07 #1
6 2517
weaknessforcats
9,208 Expert Mod 8TB
Yep. If the constructor is priviate, your code won't compile if you try to create an object using that constructor.

A private constructor is commonly used to prevent users from creating objects with it. Like a private copy constructor prevents making copies of the object forcing the users to use pointers or references in calls.
Nov 1 '07 #2
Yep. If the constructor is priviate, your code won't compile if you try to create an object using that constructor. ...
Thanks for the answer but that is not really what I meant.
I should be more specific!

This is what I have:
Expand|Select|Wrap|Line Numbers
  1. template<class T>
  2. class Singleton : public boost::noncopyable {
  3.     typedef Singleton<T> singleton_type;
  4.     typedef T object_type;
  5. public:
  6.     static object_type& getInstance() {
  7.         static object_type instance;
  8.         return instance;
  9.     }
  10.  
  11. protected:
  12.     Singleton() {}
  13.     ~Singleton() {}
  14. };
  15.  
  16. class TestClass : public Singleton<TestClass> {
  17.   friend class Singleton<TestClass>;
  18. private:
  19.   TestClass();
  20. };
  21.  
This design suffers from the fact that the user of the singleton baseclass will still have to define his Constructor as private. If it doesn't, the code will still compile clean but will break the singleton design principle.

What I wanted now is a mpl check that would test if it is at all possible to instantiate "TestClass" without using the "getInstance" method of the singleton class to emit a compile time error (possibly using BOOST_STATIC_ASSERT) and thereby enforce the Singleton pattern.

any ideas?
Nov 2 '07 #3
weaknessforcats
9,208 Expert Mod 8TB
Would you please read the article on Singleton in the C/C++ Articles forum.

There's so much wrong with your singleton hierarchy that I don't quite know where to begin.
Nov 2 '07 #4
Would you please read the article on Singleton in the C/C++ Articles forum.

There's so much wrong with your singleton hierarchy that I don't quite know where to begin.
Well my question was not really about the singleton pattern but about some way to determine if a class can be instantiated from one object or not (without forcing an compile time failure). Thats why I was hinting at some possible SFINAE solution [http://en.wikipedia.org/wiki/Substit...s_not_an_error ].

But since you mentioned some fundamental flaw in the code I posted as well
I'm of course interested what your criticism is really based on?

There are a couple of ways to go about this but I don't see how this would be a non-solution right now.

./regards

Florian
Nov 3 '07 #5
weaknessforcats
9,208 Expert Mod 8TB
1) Why is Singleton a friend to TestClass. That allows Singleton access to TestClass data members but since Singleton doesn't know about TestClass data members becuse it's a base class. This is pointless. friend classes are a big no-no.

2) The instance method is supposed to return rthe address of the Singleton and not some value like object_type. I would expect a Singleton* rather than , say, an int. That's becuse I don't know if it's an int. All I know is it's a Singleton.

3) The Singleton needs to be on the heap.

4) The Singleton needs to be identified by a name since there can probable be several Singletons. That requires a Singleton Registry.

5) The Singleton needs to set designed for Visitor.

6) The Singleton address fetched by the Instance() function should be in an anonymous namespace (or declared static in the source file containing the Singleton code) to prevent access by means other than using the Instance() method.

7) I get an error tryitng to compile TestClass.
template <class T>
class TestClass : public Singleton<TestClass> {
friend class Singleton<TestClass>;
private:
TestClass();
};
Visual Studio.NET 2005 won't accept Singleton<TestClass> because TestClass is a template and needs a type:
Expand|Select|Wrap|Line Numbers
  1. \question2007-11-01-a.cpp(19) : error C3203: 'TestClass' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
  2.         c:\scratch\instructor\question2007-11-01-a.cpp(23) : see reference to class template instantiation 'TestClass<T>' being compiled
  3.  
The template needs to be:
Expand|Select|Wrap|Line Numbers
  1. template <class T>
  2. class TestClass : public Singleton<TestClass<T> > {
  3.   friend class Singleton<TestClass<T> >;
  4. private:
  5.   TestClass();
  6. };
  7.  
How is yours compiling?

8) This won't compile:
Expand|Select|Wrap|Line Numbers
  1. TestClass<int> t;
  2.  
It needs to call Singleton::Singleton() which is private.

How are you able to create TestClass objects?

9) etc...
Nov 3 '07 #6
Thanks for taking the time ...

1) Why is Singleton a friend to TestClass. That allows Singleton access to TestClass data members but since Singleton doesn't know about TestClass data members becuse it's a base class. This is pointless. friend classes are a big no-no.
[...]
I need the friend class declaration because the constructor of TestClass needs to be private (something I still hope to be able to enforce) to fullfill the constrains of the singleton pattern. The singeton class has to be able to create the initial object during the first pass in the getInstance method.

As to the Baseclass have a look at CRTP [http://en.wikipedia.org/wiki/Curious...mplate_pattern]

2) The instance method is supposed to return rthe address of the Singleton and not some value like object_type. I would expect a Singleton* rather than , say, an int. That's becuse I don't know if it's an int. All I know is it's a Singleton.
TestClass& test = TestClass::getInstance();

3) The Singleton needs to be on the heap.
I don't see your point here. If thread safety is not of concern for me I don't see a problem. If thread safety is of interest the design can be easily enhanced so that you would force instatiation of "T" before entering main.

4) The Singleton needs to be identified by a name since there can probable be several Singletons. That requires a Singleton Registry.
Well I don't agree here either. What you are getting at is the original sample implementation of the GoF Singleton. The way I see it, these are samples, and by no means cast in stone. There are some basic rules which make a singleton a singleton. A singleton has not by definition to follow the original implementation.

Having some sort of string based lookup in some singleton registry suffers from the fact that errors (I f.ex. might have misspelled the name I registered the singleton with) would not be detected at compile time but during runtime.

Independent singletons can be instatiated independently:

Expand|Select|Wrap|Line Numbers
  1. class TestClassA : public Singleton<TestClassA> {
  2. ...
  3. };
  4.  
  5. class TestClassB : public Singleton<TestClassB> {
  6. ...
  7. };
  8.  
  9. TestClassA& a = TestClassA::getInstance();
  10. TestClassB& b = TestClassB::getInstance();
  11.  
5) The Singleton needs to set designed for Visitor.
Sorry, I don't understand. Could you elaborate on this?

6) The Singleton address fetched by the Instance() function should be in an anonymous namespace (or declared static in the source file containing the Singleton code) to prevent access by means other than using the Instance() method.
The object that I try to encapsule within the singeton is pretty much only accessible by accessing the getInstance() method of the singeton.

7) I get an error tryitng to compile TestClass.


Visual Studio.NET 2005 won't accept Singleton<TestClass> because TestClass is a template and needs a type:
Expand|Select|Wrap|Line Numbers
  1. \question2007-11-01-a.cpp(19) : error C3203: 'TestClass' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
  2.         c:\scratch\instructor\question2007-11-01-a.cpp(23) : see reference to class template instantiation 'TestClass<T>' being compiled
  3.  
The template needs to be:
Expand|Select|Wrap|Line Numbers
  1. template <class T>
  2. class TestClass : public Singleton<TestClass<T> > {
  3.   friend class Singleton<TestClass<T> >;
  4. private:
  5.   TestClass();
  6. };
  7.  
How is yours compiling?

8) This won't compile:
Expand|Select|Wrap|Line Numbers
  1. TestClass<int> t;
  2.  

It needs to call Singleton::Singleton() which is private.
It was never intended to be used that way. The excample above (and further down) should make that clearer.


How are you able to create TestClass objects?

[...]
Expand|Select|Wrap|Line Numbers
  1. template<class T>
  2. class Singleton {
  3. public:
  4.     typedef Singleton<T> singleton_type;
  5.     typedef T object_type;
  6.  
  7.     static object_type& getInstance() {
  8.         static object_type instance;
  9.         return instance;
  10.     }
  11.  
  12. protected:
  13.     Singleton() {}
  14.     ~Singleton() {}
  15.  
  16. private:
  17.     Singleton( const singleton_type& );
  18.     singleton_type& operator =( const singleton_type& );
  19. };
  20.  
  21. class TestClass : public Singleton<TestClass> {
  22.     friend class Singleton<TestClass>;
  23. public:
  24.     int someMethod() { return 0; }
  25. private:
  26.     TestClass() {}
  27. };
  28.  
  29.  
  30. int main(int /*argc*/, char* /*argv[]*/)
  31. {
  32.     TestClass& p1 = TestClass::getInstance();
  33.     p1.someMethod();
  34.     return 0;
  35. }
  36.  
This should compile clean with your copy of vs2005,
it does with mine.
Nov 5 '07 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Telos | last post by:
Ok, having trouble figuring out why this doesn't compile: class A { public: A( int x ) : _x( x ){}; private: int _x;
10
by: Ioannis Vranos | last post by:
May someone explain why does this compile? class HiddenSealBaseClass { public: HiddenSealBaseClass() { } }; class Sealed: virtual HiddenSealBaseClass
1
by: charlies224 | last post by:
Hi, I am writting a software that requires me to make sure the Num Lock is always on and Caps Lock is always off. First, I know how to detect if Num Lock or Caps Lock is on or off (if...
9
by: Don | last post by:
Is there any way to detect when an item has been added to the Items collection of a combobox or listbox? I am inheriting a Combobox and want to validate items before they are added to the...
12
by: Elad | last post by:
Hello All, Im taking an OOP course, in one of the tutorials, there was a frozen class example, i.e. a class which is impossible to inherit from, the example was something like: struct ice__ {...
6
by: pragtideep | last post by:
I am trying to understand the following code kindly help me #include<iostream> using namespace std; class base { private: ~base() {cout << "This is base destructor"<<endl ;} friend class...
9
by: RichG | last post by:
In VB 5 I could have a form named frmTest and open it with frmTest.Show Now in VB.net I have to Dim frm as New frmTest frm.show The problem is I only want one instance of frmTest open, not a...
3
by: John Salmon | last post by:
g++ complains about illegal access to a private member when the following is compiled with a private copy constructor for the class C. When the copy constructor is public, the program runs and...
12
by: Premal | last post by:
Hi, I tried to make delete operator private for my class. Strangely it is giving me error if I compile that code in VC++.NET. But it compiles successfully on VC++6.o. Can anybody give me inputs...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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...

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.