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

operator new only as static member possible?

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
(factory) class Fa.
I wanted to make that only F can call

new A

Now, I could make the operator new a private member of A. But in this case I
would have to declare Fa also as friend for A2, A3 etc.
If I would use

protected:
static void * operator(size_t t);

all the classes A,A2, A3 also could construct A, A2, A3 ... objects.

Greetings
Ernst

Jul 22 '05 #1
8 1874

"John Carson" <do***********@datafast.net.au> wrote in message
news:3f******@usenet.per.paradox.net.au...
"Robert Frunzke" <Ro**************@freenet.de> wrote in message
news:bt*************@news.t-online.com
Ernst Murnleitner wrote:
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 (factory) class Fa.
I wanted to make that only F can call

new A
You could make the constructor / all constructors private and declare
the factory as a friend.


Robert


That won't work. Consider
class A
{
friend class Fa;
private:
A()
{}
};

class A1 : public A
{
};

class A2 : public A
{
};

class Fa
{
public:
A* MakeA()
{
return new A;
}
A1* MakeA1()
{
return new A1;
}
A2* MakeA2()
{
return new A2;
}
};
int main()
{
Fa fa;
A *pa = fa.MakeA();
A1*pa1 = fa.MakeA1();
A2*pa2 = fa.MakeA2();
return 0;
}
This won't compile because, even though Fa calls new, the construction of

a derived class necessarily involves the derived class calling the constructor of the base class. If the base class constructor is private, then it cannot be called by the derived class.


So why not use a protected declaration instead of private and the code above
will work fine. Of course one should also consider how copy ctor and
assignment op are to be treated because in this version A MyObj(
*(fa.MakeA()) ); would construct an object of type A.

Chris
Jul 22 '05 #2
"Ernst Murnleitner" <mu******@awite.de> wrote in message
news:bt************@ID-130107.news.uni-berlin.de
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 (factory) class Fa.
I wanted to make that only F can call

new A

Now, I could make the operator new a private member of A. But in this
case I would have to declare Fa also as friend for A2, A3 etc.
If I would use

protected:
static void * operator(size_t t);

all the classes A,A2, A3 also could construct A, A2, A3 ... objects.

Greetings
Ernst


I can't tell you how to get exactly what you want, but you can get close.

1. Define a structure in Fa that is private and declare a static variable of
that type inside Fa.
2. Make the constructor of A take a parameter of the private type described
in 1. This will mean that only Fa and friends of Fa will be able to
construct A and its derived classes.
3. Make A and its derived classes friends of Fa. This is necessary if you
are to define the constructors of A and its derived classes.

The problem with this scheme is in point 3. Once you make them friends of
Fa, A and its derived classes will be able to construct objects from the A
hierarchy. Yet you have to make them friends or else their constructors
can't be defined.

But this should not really be a problem. A derived class will only be able
to construct objects in the A hierarchy if you make that derived class a
friend of Fa. In that case you are presumably the author of the derived
class and hence can make sure that it doesn't construct any objects in the A
hierarchy. By contrast, if a client derives from A, then the derived class
will not be a friend of Fa and hence will not be able to construct any
objects in the A hierarchy.

An example is given below:

// forward declarations
class A;
class A1;
class A2;
class Fa
{
friend class A;
friend class A1;
friend class A2;
private:
struct Faprivate{};
static Faprivate fap;
public:
A* MakeA();
A1* MakeA1();
A2* MakeA2();
};

// definition of static member
Fa::Faprivate Fa::fap;

class A
{
public:
A(Fa::Faprivate fap)
{}
};
// Note that the constructor for A1 has a parameter of
// type Fa::Faprivate even though it would be possible to
// define a constructor for A1 that took no argument and used
// Fa's static member Fa::fap in the call to the base class
// constructor. The parameter is included to stop non-friends
// of Fa from constructing A1. Similar reasoning applies to A2.
class A1 : public A
{
public:
A1(Fa::Faprivate fap) : A(fap)
{}
};

class A2 : public A
{
public:
A2(Fa::Faprivate fap) : A(fap)
{}
};
// definitions for Fa's member functions
A* Fa::MakeA()
{
return new A(fap);
}
A1* Fa::MakeA1()
{
return new A1(fap);
}
A2* Fa::MakeA2()
{
return new A2(fap);
}

int main()
{
Fa fa;
A *pa = fa.MakeA();
A1*pa1 = fa.MakeA1();
A2*pa2 = fa.MakeA2();
return 0;
}
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #3
"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:O1*****************@news.chello.at

So why not use a protected declaration instead of private and the
code above will work fine.
The OP had already considered and rejected this option.
Of course one should also consider how
copy ctor and assignment op are to be treated because in this version
A MyObj(
*(fa.MakeA()) ); would construct an object of type A.


Good point.
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)
Jul 22 '05 #4

"John Carson" <do***********@datafast.net.au> wrote in message
news:3f********@usenet.per.paradox.net.au...
"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:O1*****************@news.chello.at

So why not use a protected declaration instead of private and the
code above will work fine.


The OP had already considered and rejected this option.


Hmm, that must have slipped my attention. Sorry!

Chris
Jul 22 '05 #5
> 1. Define a structure in Fa that is private and declare a static variable
of
that type inside Fa.
2. Make the constructor of A take a parameter of the private type described in 1. This will mean that only Fa and friends of Fa will be able to
construct A and its derived classes.
3. Make A and its derived classes friends of Fa. This is necessary if you
are to define the constructors of A and its derived classes.


Thank you. Very good idea. I wanted to avoid to make Factory Fa a friend of
all A. Your solution only needs to make the A a friend of Fa which seems to
be more logicall as A do not necessary need to know anything about its
factory.

Greetings
Ernst

Jul 22 '05 #6
> You'd probably save yourself a lot of hassle by just documenting the
fact that one should only make an object from that hierarchy using
your factory.
It's almost never a good idea to place artificial restrictions on a
system, so unless you have a really good reason for this and you're
sure that no-one could ever need to create an A object by hand,
don't enforce it.


OK. But the solution of Carson is a relatively easy way to achieve, that a
certain constructor cannot used by everyone.

Greetings
Ernst

Jul 22 '05 #7

"Ernst Murnleitner" <mu******@awite.de> wrote in message
news:bt************@ID-130107.news.uni-berlin.de...
| > 1. Define a structure in Fa that is private and declare a static variable
| of
| > that type inside Fa.
| > 2. Make the constructor of A take a parameter of the private type
| described
| > in 1. This will mean that only Fa and friends of Fa will be able to
| > construct A and its derived classes.
| > 3. Make A and its derived classes friends of Fa. This is necessary if you
| > are to define the constructors of A and its derived classes.
|
| Thank you. Very good idea. I wanted to avoid to make Factory Fa a friend of
| all A. Your solution only needs to make the A a friend of Fa which seems to
| be more logicall as A do not necessary need to know anything about its
| factory.

How about the following alternative: ?

class Base
{
private:
class A
{
protected:
friend class Factory;
A() {}
public:
virtual ~A() {}
virtual void Print() { std::cout << "A" << std::endl; }
};

class A1 : public A
{
public:
void Print() { std::cout << "A1" << std::endl; }
};

class A2 : public A
{
public:
void Print() { std::cout << "A2" << std::endl; }
};

friend class Factory;
};

struct Factory : Base::A
{
typedef Base::A A;
typedef Base::A1 A1;
typedef Base::A2 A2;

static Base::A* MakeA()
{
return new Base::A;
}

static Base::A1* MakeA1()
{
return new Base::A1;
}

static Base::A2* MakeA2()
{
return new Base::A2;
}
};

int main()
{
Factory::A* Ptr = Factory::MakeA();
Ptr -> Print(); delete Ptr;

Ptr = Factory::MakeA1();
Ptr -> Print(); delete Ptr;

Ptr = Factory::MakeA2();
Ptr -> Print(); delete Ptr;

return 0;
}

The main() code is also self documenting, in that you
can clearly understand, that each object is only being
instantiated through the 'Factory' class.

Cheers.
Chris Val
Jul 22 '05 #8
>
How about the following alternative: ?

class Base
{
private:
class A
{
protected:
friend class Factory;
A() {}
public:


I think this would work, but it's an already existing application with 100,
whereby 50 classes would need this change. Therefore I wouldn't like to
change it.
Jul 22 '05 #9

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

Similar topics

47
by: Roger Lakner | last post by:
I often see operator implemented something like this: class Foo { ... }; class FooList { public: const Foo& operator (unsigned index) const {return array;}; Foo& operator (unsigned index) ...
2
by: xuatla | last post by:
Hi, I have a class myClass, and want to define operator () with it. But I don't want to change the class itself (e.g., sometime the class is defined by other people and I cannot change it), but...
5
by: Jerry Fleming | last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone says that the four operators can only be overloaded with class member functions instead of global (friend) functions: (), ,...
5
by: raylopez99 | last post by:
I need an example of a managed overloaded assignment operator for a reference class, so I can equate two classes A1 and A2, say called ARefClass, in this manner: A1=A2;. For some strange reason...
5
by: Gianni Mariani | last post by:
I'm hoping someone can tell me why using member address of works and why using the dot operator does not in the code below. The code below uses the template function resolution mechanism to...
10
by: siddhu | last post by:
Dear Experts, I want to make a class whose objects can be created only on heap. I used the following approach. class ss { ss(){} public: void* operator new(size_t sz)
2
by: aaragon | last post by:
Hi everyone, Can someone point me out why I can't declare the operator() of a functor as static? The reason behind this is that I want to be able to call to the function without instantiating...
6
by: edd | last post by:
Hello all, Is there a way to determine whether a particular type supports the -> operator at compile time? I'm trying to write a template function (or a series of overloads) that will yield the...
7
by: Bill Davy | last post by:
I want to be able to write (const char*)v where v is an item of type Class::ToolTypeT where ToolTypeT is an enumeration and I've tried everything that looks sensible. There's an ugly solution, but...
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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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?
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
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...

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.