I have a system that looks like this:
class AbstractBase { /* ... */ };
template <class T> class Impl : public AbstractBase { /* ... */ };
// ...
Impl<int> i;
Impl<float> f;
std::vector<Abs tractBase*> vec;
vec.push_back(& i);
vec.push_back(& f);
// ...
It works. However, at the moment, class AbstractBase has public
visibility - anyone can subclass it. Ideally, the only subclasses of
AbstractBase should be instantiations of Impl. Impl, on the other hand,
can (and should) be instantiable by anyone. Is it possible for me to
somehow hide AbstractBase to restrict what classes can subclass it?
Thanks,
Rennie deGraaf 12 1789
Rennie deGraaf wrote: I have a system that looks like this:
class AbstractBase { /* ... */ }; template <class T> class Impl : public AbstractBase { /* ... */ }; // ... Impl<int> i; Impl<float> f; std::vector<Abs tractBase*> vec; vec.push_back(& i); vec.push_back(& f); // ...
It works. However, at the moment, class AbstractBase has public visibility - anyone can subclass it. Ideally, the only subclasses of AbstractBase should be instantiations of Impl. Impl, on the other hand, can (and should) be instantiable by anyone. Is it possible for me to somehow hide AbstractBase to restrict what classes can subclass it?
You can make the constructor of AbstractBase private, then make Impl a
friend of AbstractBase. That way, only Impl knows how to construct the
AbstractBase sub-object.
But I'm curious, why restrict the use of AbstractBase in this way?
Hope this helps,
-shez-
Rennie deGraaf wrote: I have a system that looks like this:
class AbstractBase { /* ... */ }; template <class T> class Impl : public AbstractBase { /* ... */ }; // ... Impl<int> i; Impl<float> f; std::vector<Abs tractBase*> vec; vec.push_back(& i); vec.push_back(& f); // ...
It works. However, at the moment, class AbstractBase has public visibility - anyone can subclass it. Ideally, the only subclasses of AbstractBase should be instantiations of Impl. Impl, on the other hand, can (and should) be instantiable by anyone. Is it possible for me to somehow hide AbstractBase to restrict what classes can subclass it?
The obvious question to ask is why are AbstractBase and Impl distinct
classes to start with, if AbstractBase is meant to have only a single
subclass.
Greg
Greg wrote: The obvious question to ask is why are AbstractBase and Impl distinct classes to start with, if AbstractBase is meant to have only a single subclass.
From the OP's code, it looks like he wants to create a vector
containing heterogenous objects. The problem with his approach is that
the <AbstractBase *> parameter for vector does not preserve value
semantics. A better approach would be to use something boost::any or
boost::variant, where value-semantics are maintained.
-shez-
Greg wrote: Rennie deGraaf wrote:
I have a system that looks like this:
class AbstractBase { /* ... */ }; template <class T> class Impl : public AbstractBase { /* ... */ }; // ... Impl<int> i; Impl<float> f; std::vector<Abs tractBase*> vec; vec.push_back(& i); vec.push_back(& f); // ...
It works. However, at the moment, class AbstractBase has public visibility - anyone can subclass it. Ideally, the only subclasses of AbstractBas e should be instantiations of Impl. Impl, on the other hand, can (and should) be instantiable by anyone. Is it possible for me to somehow hide AbstractBase to restrict what classes can subclass it?
The obvious question to ask is why are AbstractBase and Impl distinct classes to start with, if AbstractBase is meant to have only a single subclass.
Greg
What I need is an STL container (I'm actually using an std::map, but an
std::vector was simpler for the example) containing a bunch of different
instantiations of Impl. In other words, a container can can store an
Impl<int> and an Impl<string>, but not an int or a string. AFAIK, C++
doesn't define references or pointers to templates, only to template
instantiations, so I need to refer to objects of Impl<int> and
Impl<string> through a base class.
Since the STL doesn't seem to play nicely with polymorphic types, I have
to store pointers to my objects, rather than the objects themselves, and
handle allocation myself. It's a pain, but I don't know any better
ways. I'm open to suggestions, if you have them.
Rennie
Rennie deGraaf wrote: What I need is an STL container (I'm actually using an std::map, but an std::vector was simpler for the example) containing a bunch of different instantiations of Impl. In other words, a container can can store an Impl<int> and an Impl<string>, but not an int or a string. AFAIK, C++ doesn't define references or pointers to templates, only to template instantiations, so I need to refer to objects of Impl<int> and Impl<string> through a base class.
Since the STL doesn't seem to play nicely with polymorphic types, I have to store pointers to my objects, rather than the objects themselves, and handle allocation myself. It's a pain, but I don't know any better ways. I'm open to suggestions, if you have them.
As shezan suggested, you can solve this by having private Constructor
in AbstractBase
#include <vector>
class AbstractBase {
protected:
virtual ~AbstractBase() { }
private:
AbstractBase(){ }
template<class T> friend class Impl;
};
template <class T> class Impl : public AbstractBase {
T i;
};
class Zoo : public AbstractBase {
};
// Zoo cannot be instantiated because constructor of base class is
private.
int main()
{
Impl<int> i;
Impl<float> f;
// Zoo z; // not allowed
std::vector<Abs tractBase*> v;
v.push_back(&i) ;
v.push_back(&f) ;
// v.push_back(&z) ; // Error.
}
Rennie deGraaf wrote: Since the STL doesn't seem to play nicely with polymorphic types, I have to store pointers to my objects, rather than the objects themselves, and handle allocation myself. It's a pain, but I don't know any better ways. I'm open to suggestions, if you have them.
I guess I should rephrase my original question so: What virtual
functions are you going to have in 'AbstractBase'? If there are no
virtual functions, there should be no need for inheritance. If there
*are* virtual functions, when why make 'AbstractBase' completely
hidden?
I suggested 'boost::any' earlier, but if you want to restrict your
container to only contain 'Impl' objects, then it is reasonably
straightforward to adapt 'boost::any' to restrict only 'Impl' types.
Something like:
class AnyImpl {
// PRIVATE DATA MEMBERS
boost::any d_any;
public:
template <typename TYPE>
AnyImpl(const Impl<TYPE>& value) : d_any(value) { }
template <typename TYPE>
AnyImpl& operator=(const Impl<TYPE>& value) { d_any = value; }
};
Now you can create vector<AnyImpl> or map<AnyImpl, AnyImpl>.
Hope this helps,
-shez-
Shezan Baig wrote: Rennie deGraaf wrote:
I have a system that looks like this:
class AbstractBase { /* ... */ }; template <class T> class Impl : public AbstractBase { /* ... */ }; // ... Impl<int> i; Impl<float> f; std::vector<Abs tractBase*> vec; vec.push_back(& i); vec.push_back(& f); // ...
It works. However, at the moment, class AbstractBase has public visibility - anyone can subclass it. Ideally, the only subclasses of AbstractBas e should be instantiations of Impl. Impl, on the other hand, can (and should) be instantiable by anyone. Is it possible for me to somehow hide AbstractBase to restrict what classes can subclass it?
You can make the constructor of AbstractBase private, then make Impl a friend of AbstractBase. That way, only Impl knows how to construct the AbstractBase sub-object.
Of course, doing this would make *all* of AbstractBase's private methods
and data accessible to Impl. Is it possible to only make Impl's
constructor a friend to AbstractBase? I can't find anything on the
subject, and can't figure out any syntax that compiles.
But I'm curious, why restrict the use of AbstractBase in this way?
My code assumes that all objects that it pulls out of vec are
instantiations of Impl. If someome subclasses AbstractBase with
something else and gets it into vec, then my code with throw an
exception with an error message that assumes a completely different
problem. My code can't tell the difference between a specialization of
Impl that it doesn't know about and something that isn't an Impl at all.
Also, I intend people using my system to write specializations of Impl,
and don't want to make it possible for people to get confused and try to
subclass AbstractBase instead. If I make Impl a friend of AbstractBase
and make AbstractBase's constructor private, then this can't happen, but
then people might mess around with AbstractBase's private data and
totally s*crew up the system. Neither is a critical problem (unless
someome finds a way to make a buffer overflow or something out of it),
but I'd rather have neither, and I'm not sure which is worse.
Rennie
> Rennie deGraaf" <ca.ucalgary.cp sc@degraaf> wrote: Rennie deGraaf wrote:
I have a system that looks like this:
class AbstractBase { /* ... */ }; template <class T> class Impl : public AbstractBase { /* ... */ }; // ... Impl<int> i; Impl<float> f; std::vector<Abs tractBase*> vec; vec.push_back(& i); vec.push_back(& f); // ...
It works. However, at the moment, class AbstractBase has public visibility - anyone can subclass it. Ideally, the only subclasses of AbstractBase should be instantiations of Impl. Impl, on the other hand, can (and should) be instantiable by anyone. Is it possible for me to somehow hide AbstractBase to restrict what classes can subclass it?
What I need is an STL container (I'm actually using an std::map, but an std::vector was simpler for the example) containing a bunch of different instantiations of Impl. In other words, a container can can store an Impl<int> and an Impl<string>, but not an int or a string. AFAIK, C++ doesn't define references or pointers to templates, only to template instantiations, so I need to refer to objects of Impl<int> and Impl<string> through a base class.
Since the STL doesn't seem to play nicely with polymorphic types, I have to store pointers to my objects, rather than the objects themselves, and handle allocation myself. It's a pain, but I don't know any better ways. I'm open to suggestions, if you have them.
I would suggest looking into a discriminated union or similar, variant type
(such as Boost's variant) as an alternative solution. I think either of
those approaches would involve less "housekeepi ng" chores, require fewer
lines code, and overall be simply easier to manage than the implementation
described above. The benefit of a union or variant class derives from having
just one class do the work currently slated for one base class and several,
derived classes - in short - an entire class hierarchy.
Greg
"Neelesh Bodas" <ne***********@ gmail.com> skrev i meddelandet
news:11******** ************@g1 4g2000cwa.googl egroups.com... Rennie deGraaf wrote: What I need is an STL container (I'm actually using an std::map, but an std::vector was simpler for the example) containing a bunch of different instantiations of Impl. In other words, a container can can store an Impl<int> and an Impl<string>, but not an int or a string. AFAIK, C++ doesn't define references or pointers to templates, only to template instantiations, so I need to refer to objects of Impl<int> and Impl<string> through a base class.
Since the STL doesn't seem to play nicely with polymorphic types, I have to store pointers to my objects, rather than the objects themselves, and handle allocation myself. It's a pain, but I don't know any better ways. I'm open to suggestions, if you have them. As shezan suggested, you can solve this by having private Constructor in AbstractBase
#include <vector>
class AbstractBase { protected: virtual ~AbstractBase() { } private: AbstractBase(){ } template<class T> friend class Impl;
};
template <class T> class Impl : public AbstractBase { T i; };
class Zoo : public AbstractBase { }; // Zoo cannot be instantiated because constructor of base class is private.
But it doesn't stop the pervasive intruder!
struct ooZ {};
template<>
class Impl<ooZ> : public AbstractBase {
// whatever Zoo wants to do!
};
typedef Impl<ooZ> Zoo; int main() { Impl<int> i; Impl<float> f; // Zoo z; // not allowed
Now it is allowed! std::vector<Abs tractBase*> v; v.push_back(&i) ; v.push_back(&f) ;
// v.push_back(&z) ; // Error.
} This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Dan =o\) |
last post by:
given this brief scenario, is this possible somehow?
class A
{
public SomeMethod()
{
}
}
|
by: mdb |
last post by:
I'm trying to restrict the characters that are valid in a textBox, so I
derived from System.Windows.Forms.TextBox, and overrode WndProc, catching
the key up/down messages... Everything works except the arrow keys - the
text cursor never moves. Why won't the arrows work? I know I'm catching
the correct WParam values...
protected override void WndProc(ref Message m)
{
if ((m.Msg == 256) || (m.Msg == 258))
{
|
by: clintonG |
last post by:
I've created a base class that inherits from System.Web.UI.Page.
I've been using Page_PreInit in the base class to change Themes.
I'm using MasterPages and need a bunch of code in each content page to
manage the UI. For the most part this UI code is the same across many pages
although their will be some conditional circunstances. So I thought "put the
logic in the base class so I don't even have to call any methods in each
content page."...
|
by: Piper707 |
last post by:
Hi,
I'd like to know if there are any more ways of restricting an XML
document to having only non-empty tags (containing Strings).
I can think of 2 ways:
1)
<xs:simpleType name="tagName">
|
by: EqDev |
last post by:
I have a class that is a control derived from UserControl. I want to use
serialization and deserialization with this calss but I get an exception
"Cannot serialize member System.ComponentModel.Component.Site of type
System.ComponentModel.ISite because it is an interface.".
I am not interested in serializing any member from the base class only the
properties in the derived class.
How can I prevent the entire base class from being...
| |
by: Colin Desmond |
last post by:
Is it possible to write an attribute that changes the visibility of a class
(public/private) etc based on some pre-compiler define symbol?
We're writing some classes which will be called by an external (bespoke)
test harness, so we want then to be public in the assembly when we're
testing, and private in the class the rest of the time.
For example
|
by: Darren.Ratcliffe |
last post by:
Hi guys
Posted what was probably a rather confusing post about this the other
day, so I am going to have another go and see if I can make more sense.
This sis purely a
I've got a base class called animal, and from within animal you can
access lots more classes such as feline, canine, reptile and
amphibian.....
|
by: WittyGuy |
last post by:
Hi
My class looks something like this:
class Base
{
public:
Base () {}
~Base () {} // No virtual dtor in the base class
private:
};
|
by: Janis Papanagnou |
last post by:
The task seems simple but I am not sure whether this is possible or even
the right way to look at it...
I have <td class="X"elements where "X" is a placeholder for class names
"A", "B", etc. Now I want to display/hide all <tdelements of a certain
class, say "A". The static CSS equivalent would be
<style type="text/css">
.A { visibility:visible; }
.B { visibility:hidden; }
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
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 then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |