473,796 Members | 2,591 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is it valid to initialize a base class with placement new?

Assume I have a class Base, and then this:

struct Derived: public Base
{
AnotherClass member;
};

Also assume that I'm allocating an object of type 'Derived' with a
custom allocator and that, for whatever reason, I don't want to call the
constructor of 'Derived', but instead I want to build the object by
first making a placement new for the 'Base' and then another for the
'member'. (Yes, I know this might sound like a bit of a silly thing to
want, but just humor me, please.) Is it valid to do that?

The code would be something like this:

Derived* ptr = allocator.alloc ate(1);
new (static_cast<Ba se*>(ptr)) Base(baseParame ters);
new (&ptr->member) AnotherClass(ot herParameters);

This compiles (and doesn't crash), but is it valid?
Sep 3 '08
19 1932
On 3 Sep, 22:17, Juha Nieminen <nos...@thanks. invalidwrote:
* Assume I have a class Base, and then this:

struct Derived: public Base
{
* * AnotherClass member;

};
[snip]
* The code would be something like this:

Derived* ptr = allocator.alloc ate(1);
new (static_cast<Ba se*>(ptr)) Base(baseParame ters);
new (&ptr->member) AnotherClass(ot herParameters);

* This compiles (and doesn't crash), but is it valid?
As others have pointed out, it is not valid (UB). If you want a
concrete refutation from the standard, see 12.7/1

"For an object of non-POD class type (clause 9), before the
constructor begins execution and after the destructor finishes
execution, referring to any nonstatic member or base class of the
object results in undefined behavior"

DP
Sep 5 '08 #11
Thomas J. Gritzan wrote:
However, why don't you simple do:
new (static_cast<vo id*>(ptr)) Derived(paramet ers);
Since the number of parameters can be anything, I would need to use a
variadic template to forward the parameters to the constructor of the
member variable. (I can't assume that the member variable supports
copy-constructing.)

Well, I ended up with a compromise: I created 7 constructors for
'Derived', taking 0-6 parameters. Hopefully up to 6 parameters will be
enough until the next C++ standard is widely implemented...
Sep 5 '08 #12
to***********@y ahoo.co.uk wrote:
Just use a preprocessor macro (assuming you're using a capable
compiler)...
You mean using a macro with a variable number of arguments? Is that
standard C++ yet?
Sep 5 '08 #13
On 5 Sep, 11:19, Juha Nieminen <nos...@thanks. invalidwrote:
* Since the number of parameters can be anything, I would need to use a
variadic template to forward the parameters to the constructor of the
member variable. (I can't assume that the member variable supports
copy-constructing.)

* Well, I ended up with a compromise: I created 7 constructors for
'Derived', taking 0-6 parameters. Hopefully up to 6 parameters will be
enough until the next C++ standard is widely implemented...
What compiler are you currently using? GCC 4.3+ has variadic
templates, FWIW.

DP
Sep 5 '08 #14
On Sep 5, 6:21*pm, Juha Nieminen <nos...@thanks. invalidwrote:
tony_in_da...@y ahoo.co.uk wrote:
Just use a preprocessor macro (assuming you're using a capable
compiler)...

* You mean using a macro with a variable number of arguments? Is that
standard C++ yet?
Nope, but it's very widely supported and better than undefined
behaviour.

Tony
Sep 5 '08 #15
Triple-DES wrote:
What compiler are you currently using? GCC 4.3+ has variadic
templates, FWIW.
Yes, but I'm making a library I'm going to distribute, so I have to
stick to the current C++ standard...
Sep 5 '08 #16
Alf P. Steinbach wrote:
You have a bad design, and try to compensate with bad coding.

Instead fix the design.
In this case it's more a question of language limitation (fixed in
C++0x) than design.
Sep 5 '08 #17
Alf P. Steinbach wrote:
Have you considered replacing

Derived* ptr = allocator.alloc ate(1);
new (static_cast<Ba se*>(ptr)) Base(baseParame ters);
new (&ptr->member) AnotherClass(ot herParameters);

with e.g.

Derived d( new AnotherClass( otherParameters ) );

Just for example?
In this application in question that's precisely what I'm trying to
avoid. (The app in question would become completely moot.)

Ok, enough riddles. I made something which I think should work about
ok, and a webpage for it:

http://warp.povusers.org/RefPtr/

Probably not a novel idea, but it might be useful to someone, maybe.

("Why not simply use boost::shared_p tr?" Because boost::shared_p tr has
the size of two pointers and a payload of a whopping 44 bytes, at least
with linux gcc, making each (unshared) shared_ptr instance consume a
grand total of 56 bytes of RAM in a 32-bit system (2*4 bytes for the two
pointers, 44 bytes for the payload and 4 bytes for the clib memory
allocator payload), while my RefPtr consumes a grand total of 8 bytes
(sizeof(RefPtr) = 4, plus the intrusive reference counter). Sure, it's
not as versatile, but in many situations that doesn't matter.)
Sep 5 '08 #18
Juha Nieminen schrieb:
Alf P. Steinbach wrote:
>Have you considered replacing

Derived* ptr = allocator.alloc ate(1);
new (static_cast<Ba se*>(ptr)) Base(baseParame ters);
new (&ptr->member) AnotherClass(ot herParameters);

with e.g.

Derived d( new AnotherClass( otherParameters ) );

Just for example?

In this application in question that's precisely what I'm trying to
avoid. (The app in question would become completely moot.)
How about this:

struct Holder
{
unsigned char SomeSpace[sizeof(...)];
size_t Count;
};

Holder* ptr = allocator.alloc ate(1);
new (ptr) Holder(basePara meters);
new (ptr->SomeSpace) AnotherClass(ot herParameters);
Ok, enough riddles. I made something which I think should work about
ok, and a webpage for it:

http://warp.povusers.org/RefPtr/

Probably not a novel idea, but it might be useful to someone, maybe.
Do you know this article? (by Andrei Alexandrescu)
http://www.informit.com/articles/art...31529&seqNum=6
On the following pages it describes some useful technics for smart
pointer implementations .

--
Thomas
Sep 5 '08 #19
Thomas J. Gritzan wrote:
How about this:

struct Holder
{
unsigned char SomeSpace[sizeof(...)];
size_t Count;
};

Holder* ptr = allocator.alloc ate(1);
new (ptr) Holder(basePara meters);
new (ptr->SomeSpace) AnotherClass(ot herParameters);
That might be one possible solution (at least to avoid having to write
all the constructors, or the variadic template constructor).
Sep 6 '08 #20

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

Similar topics

0
3640
by: Tao | last post by:
I just upgraded .NET framework to 1.1 and VS.Net to 2003 version and tried to test it out. I created an ASP.NET project using the wizard and tried to run it by hitting "F5". I got an exception: "Specified cast is not valid." The only thing i put there was a "test this." inside the form. What might be the problem here? Thanks in advance. The Exception:
8
1432
by: block111 | last post by:
I'm a student in a university and today we had a final exam in c++. Basicly, I was amazed by the amount of lame and invalid examples/questions. There was a question that in practice works but is a really big mistake (as far as I'm concerned). So, I'll need to prove why exactly it was wrong. Here is the example: int *p1, *p2, x = 3; p1 = new int; *p1 = 60;
5
2930
by: removeps-generic | last post by:
Hi. I'm using placement new to re-initialize part of an object. Is this OK? struct BaseImp { All& r_all; BaseImp(All& all) : r_all(all) }; struct Calc::Imp : public BaseImp
18
4216
by: toton | last post by:
Hi, In C++ when I initialize an array it, also initializes the class that it contains, which calls the default constructor. However, I want to initialize the array only (i.e reserve the space) and use my specific constructor to initialize the class. How to do it without using malloc? Something like Point* pt = new Point; I want it to reserve the space for N points only, and not to call default constructor. I dont have a default...
15
3538
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and you want to make a deque which can contain any objects of any of those types. Normally what you would have to do is to make a deque or vector of pointers of the base class type and then allocate each object dynamically with 'new' and store the...
11
2338
by: Bob Altman | last post by:
Hi all, I have a class that contains a member variable that is an array of class instances: class MyClass { private: SomeClass m_someClass; SomeClass m_arrayOfClasses; };
0
9684
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, 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...
0
10459
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10182
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6793
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();...
0
5445
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...
0
5577
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4120
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
2
3734
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2928
bsmnconsultancy
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...

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.