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

How can I insure that the objects of a class must be allocated in the heap?

Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?

Thanks,
Peng

Nov 9 '05 #1
10 2092
Pe*******@gmail.com wrote:
Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?

Thanks,
Peng


Make all the constructors private and then declare friend functions to
allocate objects

class X
{
private:
X();
X(int, int);
X(const X&);
public:
...
friend X* make_X() { return new X(); }
friend X* make_X(int a, int b) { return new X(a, b); }
friend X* copy_X(X* rhs) { return new X(*rhs); }
};

john
Nov 9 '05 #2
* Pe*******@gmail.com:

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?
There are two ways: (1) restrict access to constructors _and_ provide
factory functions for all relevant constructors in all relevant classes,
or (2) restrict access to your destructor.

(1)
is covered in the FAQ -- go find! ;-)

(2)
which I like much better (less work, doing things once and for all), at
least until someone tells me what the Big Drawback is, is partially
covered in section 1.3.1 of <url:
http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>

In addition to the discussion there -- it's an unfinished document --
you'd probably be a happier and more productive programmer if the
once-and-for-all support includes something like

template<
typename T,
void (*defaultDestructionFunction)(T*) = &::callDelete<T>

class SharedPtr: public boost::shared_ptr<T>
{
private:
typedef boost::shared_ptr<T> Base;
public:
// Ordinary construction:
SharedPtr(): Base() {}
SharedPtr( Base const& r ) throw(): Base( r ) {}
SharedPtr( T* p ): Base( p, defaultDestructionFunction ) {}
template< typename Destroyer >
SharedPtr( T* p, Destroyer d ): Base( p, d ) {}

// Special converting construction:
template< class Y >
SharedPtr( boost::shared_ptr<Y> const& r ) throw(): Base( r ) {}
template< class Y >
explicit SharedPtr( boost::weak_ptr<Y> const& r ): Base( r ) {}
template< class Y >
explicit SharedPtr( std::auto_ptr<Y>& r ): Base( r ) {}
};

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 9 '05 #3
Pe*******@gmail.com wrote:
Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?


First, I do not quite understand, why you would want to do something like
that.

As for how you could go about it, here is an idea: You can make the
constructors private. Now, that sounds silly as it prevents construction.
However, you can have a friend. This way, only the friend class is able to
construct objects. If that friend happens to only allocate objects via new,
then you are fine. E.g.:
#include <algorithm>
#include <iostream>

class handle;

class forbidden {

friend class handle;

int i;

forbidden ( int j = 0 )
: i ( j )
{
std::cout << "created\n";
}

~forbidden ( void ) {
std::cout << "destroyed\n";
}

forbidden ( forbidden const & other );
forbidden& operator= ( forbidden const & other );

public:

int get ( void ) const {
return ( i );
}

int set ( int j ) {
i = j;
return j;
}

}; // class forbidden

class handle {

forbidden* ptr;

public:

handle ( int i = 0 )
: ptr ( new forbidden ( i ) )
{}

handle ( handle const & other )
: ptr ( new forbidden ( other.get() ) )
{}

~handle ( void ) {
delete ptr;
}

handle & operator= ( handle const & other ) {
handle dummy ( other );
std::swap( this->ptr, dummy.ptr );
return ( *this );
}

int get ( void ) const {
return ( ptr->get() );
}

int set ( int i ) {
return( ptr->set(i) );
}

}; // handle

int main ( void ) {
handle x ( 5 );
std::cout << x.get() << '\n';
}
Note that this handle has value semantics. It is quite easy to implement
reference semantics instead.

If you just want to allow pointers to forbidden object but not forbidden
objects, you could do something like this:

#include <algorithm>
#include <iostream>

struct handle;

class forbidden {

friend class handle;

int i;

forbidden ( int j = 0 )
: i ( j )
{
std::cout << "created\n";
}

forbidden ( forbidden const & other );
forbidden& operator= ( forbidden const & other );

public:

int get ( void ) const {
return ( i );
}

int set ( int j ) {
i = j;
return j;
}

~forbidden ( void ) {
std::cout << "destroyed\n";
}

}; // class forbidden

struct handle {

static
forbidden* new_forbidden ( int i = 0 ) {
return( new forbidden ( i ) );
}

}; // handle

int main ( void ) {
forbidden* f_ptr = handle::new_forbidden ( 5 );
std::cout << f_ptr->get() << '\n';
delete f_ptr;
}

Anyway, it just seems like you want to make life harder for the clients of
your code. Generally, that is not a good idea: next week, someone will post
the question as to how your measures can be circumvented.
Best

Kai-Uwe Bux
Nov 9 '05 #4
* Kai-Uwe Bux:
Pe*******@gmail.com wrote:
Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?
First, I do not quite understand, why you would want to do something like
that.


For example, a recursive data structure can/should have a recursive
cleanup operation, which needs all objects to be dynamically allocated.

As for how you could go about it, here is an idea: You can make the
constructors private.


See my earlier reply in this thread for a code-it-once-and-for-all
alternative that, so far!, I like much better... ;-)

In addition to what I wrote there, there is a tools issue: for a class
Foo the Visual 7.1 compiler incorrectly allows it to be used as a member
in a class Bar that doesn't define a destructor, but the compiler issues
a warning, and class Bar will generate errors on all practical usage.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 9 '05 #5
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Pe*******@gmail.com wrote:
> Hi,
>
> Maybe this is an simple question. How can I insure that the objects of
> a class must be allocated in the heap?


First, I do not quite understand, why you would want to do something like
that.


For example, a recursive data structure can/should have a recursive
cleanup operation, which needs all objects to be dynamically allocated.


Hm, I see what you mean.

However, in such a case, I would probably have some container type and some
node type. The node type would be invisible to the clients of the
container. In that case, I do not see any reason to make myself go through
hoops to make sure that I never create a local node variable (which
actually could be useful, provided you know what you are doing). Usually, I
feel no urge to tie my hands.

On the other hand, there might be dynamic data structures in client
territory, not mediated through iterators. For those, I can see that you
have a valid point. But aren't those dangerous anyway?
Thanks

Kai-Uwe Bux

Nov 9 '05 #6
Kai-Uwe Bux wrote:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Pe*******@gmail.com wrote:

> Hi,
>
> Maybe this is an simple question. How can I insure that the objects of
> a class must be allocated in the heap?

First, I do not quite understand, why you would want to do something like
that.


For example, a recursive data structure can/should have a recursive
cleanup operation, which needs all objects to be dynamically allocated.


Hm, I see what you mean.

However, in such a case, I would probably have some container type and some
node type. The node type would be invisible to the clients of the
container. In that case, I do not see any reason to make myself go through
hoops to make sure that I never create a local node variable (which
actually could be useful, provided you know what you are doing). Usually, I
feel no urge to tie my hands.

On the other hand, there might be dynamic data structures in client
territory, not mediated through iterators. For those, I can see that you
have a valid point. But aren't those dangerous anyway?


Although not very common, there are instances when requiring
heap-allocated storage for an object is a necessity. These cases
usually arise whenever an object's lifespan extends beyond the current
scope, or the object is shared across threads or is a member of a
cache.

Relying on every programmer to "know" that a certain class of object
must be allocated on the heap is a surefire way for the program to end
up with a stack-allocated object someday. The reason would be that it
is often not apparent when any of the three situations mentioned above
may apply to an object (or at least not apparent to anyone who hasn't
spent years working on the program). So there has to be a failsafe
mechanism that will catch bugs at the ideal time: before they have been
added to the source code.

Greg

Nov 9 '05 #7
Pe*******@gmail.com wrote:
Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?


The answer to your question is to fix the emotional problem that causes
you to obsess over how people will use the class that you write.

It's like asking ``How can I ensure that only jazz will ever be played
on the guitar that I am building?''

Nov 9 '05 #8
Use a singleton and make sure that the static copy that all the
references refer to is allocated on the heap.

Nov 9 '05 #9
> > Hi,

Maybe this is an simple question. How can I insure that the objects of
a class must be allocated in the heap?


The answer to your question is to fix the emotional problem that causes
you to obsess over how people will use the class that you write.

It's like asking ``How can I ensure that only jazz will ever be played
on the guitar that I am building?''

That's not the same at all and there's no emotional problems with that.
Read previous post by Greg, where he precisely describes cases where
you just have to insure that objects are only heap-allocatable; or,
sometime later, perfectly valid code will behave unexpectedly

Nov 9 '05 #10
Greg wrote:
Kai-Uwe Bux wrote:
Alf P. Steinbach wrote:
> * Kai-Uwe Bux:
>> Pe*******@gmail.com wrote:
>>
>> > Hi,
>> >
>> > Maybe this is an simple question. How can I insure that the objects
>> > of a class must be allocated in the heap?
>>
>> First, I do not quite understand, why you would want to do something
>> like that.
>
> For example, a recursive data structure can/should have a recursive
> cleanup operation, which needs all objects to be dynamically allocated.
[snip]
Although not very common, there are instances when requiring
heap-allocated storage for an object is a necessity. These cases
usually arise whenever an object's lifespan extends beyond the current
scope, or the object is shared across threads or is a member of a
cache.
That objects may need to be dynamically allocated is true. However, I have a
hard time to picture a clear cut case, where that is a reasonable
requirement for *all* objects of a given class type. That, however, is the
issue here.
Relying on every programmer to "know" that a certain class of object
must be allocated on the heap is a surefire way for the program to end
up with a stack-allocated object someday.
Here you make a sweeping generalization from object to class of objects.
The reason would be that it
is often not apparent when any of the three situations mentioned above
may apply to an object (or at least not apparent to anyone who hasn't
spent years working on the program). So there has to be a failsafe
mechanism that will catch bugs at the ideal time: before they have been
added to the source code.

Best

Kai-Uwe Bux

Nov 10 '05 #11

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

Similar topics

9
by: cppaddict | last post by:
I have a method that uses a fairly large object. The choice is between having a local object in the method or a static member object that the method uses. ------CHOICE 1--------- int...
14
by: Olumide | last post by:
In the following C++ class, MyClass{ // Members } From which I create two objects (using the default constructor), (1) MyClass *object1 = new MyClass(); // Stack (2) MyClass object2 =...
5
by: Gomaw Beoyr | last post by:
Hello Is there any explanation why Microsoft chose to implement arrays as objects allocated on the heap instead of structs allocated on the stack? For "mathematical stuff", one normally...
9
by: thomson | last post by:
Hi all, Would you please explain me where will be the heap stored if it is declared inside the Class, As class is a reference type, so it gets stored on the heap, but struct is a value...
14
by: luis | last post by:
Are basic types (int, long, ...) objetcs or not? I read that in C# all are objects including basic types, derived from Object class. Then in msdn documentation says that boxing converts basic...
1
by: Bae,Hyun-jik | last post by:
Where are __value objects allocated? I guess __value object is same to basic __value objects such as int,char,float, but C# compiler demands using new keyword even to __value classes. Please...
5
by: pitdog | last post by:
Hello, I am unable to find information on about this issue so I thought I would post and ask. I have a class that is using the sigleton pattern as it has an internal static instance of...
7
by: Jo | last post by:
Hi, How can i differentiate between static and dynamic allocated objects? For example: void SomeFunction1() { CObject *objectp = new CObject; CObject object;
55
by: tonytech08 | last post by:
How valuable is it that class objects behave like built-in types? I appears that the whole "constructor doesn't return a value because they are called by the compiler" thing is to enable...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
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: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: 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...
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...

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.