473,714 Members | 2,464 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

accessing protected data members of instance of parent class

Hi,

Given: I have a class with protected or private data members, some of
them without accessor methods. It's someone else's class, so I can't
change it. (eg, I can't add accessor methods to the parent class, and I
can't make some "helper" class a friend of the parent class to help in
accessing the data.)

Problem: I want to derive a class that has a copy constructor that
properly copies those data members.

What I tried:
1. I tried using memcpy() to copy all the data members. That always
crashed if the derived class contained virtual functions (?!), and
sometimes even more times than that.

class Derived
{.....
public:
Derived(Parent& rhs)
{
memcpy(this, &rhs, sizeof(Parent)) ;
}
}

*** What gives? Why doesn't this work?
I'm guessing I'm not copying rhs into the proper portion of Derived's
memory layout. :-/

2. I tried static_casting the parent class to the derived class, so that
I could gain access to its data members directly.

class Derived
{.....
public:
Derived(Parent& rhs)
{
dataMemberX = static_cast<Der ived&>(rhs).dat aMemberX;
}
}

*** Is this *safe*? ie, Is it safe to static_cast from one instance down
to a *derived* class, even if that instance wasn't originally created of
the derived type?

Seems to me that sometimes this will work (as it has every time I've
*tried* it), and sometimes I'll get a mem access exception because the
derived class is bigger than the parent class.

3. *** Anyone have better suggestions for what else I might try? ;-)
Hacks are welcome, as long as they're "safe".

Thanks!
Suzanne

Jul 22 '05 #1
5 3650
"Suzanne Vogel" <su************ *@hotmail.com> wrote in message
news:3f******** **@news.unc.edu ...
| Given: I have a class with protected or private data members, some of
| them without accessor methods. It's someone else's class, so I can't
| change it. (eg, I can't add accessor methods to the parent class, and I
| can't make some "helper" class a friend of the parent class to help in
| accessing the data.)
|
| Problem: I want to derive a class that has a copy constructor that
| properly copies those data members.
|
| What I tried:
| 1. I tried using memcpy() to copy all the data members.

This leads to undefined behavior (except for PODs=C-like structs).
| 2. I tried static_casting the parent class to the derived class,
| so that I could gain access to its data members directly.
....
| *** Is this *safe*? ie, Is it safe to static_cast from one instance down
| to a *derived* class, even if that instance wasn't originally created of
| the derived type?

No, formally not. Although it will work on many implementations if you
only access base class members and avoid any virtual/dynamic methods.
| 3. *** Anyone have better suggestions for what else I might try? ;-)
| Hacks are welcome, as long as they're "safe".

You haven't said wheter the Parent class had an accessible
copy-constructor.
But the nice clean way to do it is:
class Derived : public Parent // this relationship assumed
{.....
public:
Derived(Parent& rhs)
: Parent( rhs ) // initialize Parent sub-object with rhs
{
// ... whatever else is needed ...
}
};
I hope this helps,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
Jul 22 '05 #2
> | Given: I have a class with protected or private data members, some of
| them without accessor methods. It's someone else's class, so I can't
| change it. (eg, I can't add accessor methods to the parent class, and I
| can't make some "helper" class a friend of the parent class to help in
| accessing the data.)
|
| Problem: I want to derive a class that has a copy constructor that
| properly copies those data members.
[snip]
| 3. *** Anyone have better suggestions for what else I might try? ;-)
| Hacks are welcome, as long as they're "safe".

You haven't said wheter the Parent class had an accessible
copy-constructor.
No, the parent class does not have a copy constructor -- or even an
assignment operator. :-( But thanks for the suggestion.

*** Any suggestions that do *not* require the parent to have a copy
constructor or assignment operator?

eg, I have an idea: I've broadened my scope from requiring copying done
within the copy constructor, to permitting it down from outside. The
difference here is that I'm typecasting the derived instance *up* to the
parent class (rather than trying to typecast the parent down to the
derived class, which is unsafe).

*** Is this safe & guaranteed to work in all cases?

Parent* p = new Parent(...);
Derived* d = new Derived();
memcpy(static_c ast<Parent*>(d) , p, sizeof(Parent)) ; // copy p to d

Thanks again!

Suzanne
But the nice clean way to do it is:
class Derived : public Parent // this relationship assumed
{.....
public:
Derived(Parent& rhs)
: Parent( rhs ) // initialize Parent sub-object with rhs
{
// ... whatever else is needed ...
}
};
I hope this helps,
Ivan


Jul 22 '05 #3
"Suzanne Vogel" <su************ *@hotmail.com> wrote in message
news:3f******** @news.unc.edu.. .
| > You haven't said wheter the Parent class had an accessible
| > copy-constructor.
|
| No, the parent class does not have a copy constructor -- or even an
| assignment operator. :-( But thanks for the suggestion.

Sorry to be picky here, but you have to be specific.
If the parent class doesn't have (*declare*) a copy-constructor or
assignment operator, a default compiler-generated implementation
of these functions will exist and be accessible.
If the parent class defines them as public or protected members,
they can only be used.
Only if those members are declared as private will you not
be able to use the solution I suggested.

| *** Any suggestions that do *not* require the parent to have a copy
| constructor or assignment operator?

If both of these operations as declared as *private* in the parent,
the C++ standard will not allow you to portably work around the
intent of what has been written.

| *** Is this safe & guaranteed to work in all cases?
|
| Parent* p = new Parent(...);
| Derived* d = new Derived();
| memcpy(static_c ast<Parent*>(d) , p, sizeof(Parent)) ; // copy p to d

I would stay away from memcpy. It does lead to real problems
(not only in theory, though it depends on the contents of Parent).

If you really need a hack, the following might be more
reliable:

// File: Derived.cpp
#define private public //illegal, but typically works in practice...
#include "Parent.h"
#undef private
//... other includes ...
// and use the copy-constructor of Parent,
// as suggested in my previous reply

hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
Jul 22 '05 #4
> | No, the parent class does not have a copy constructor -- or even an
| assignment operator. :-( But thanks for the suggestion.

Sorry to be picky here, but you have to be specific.
If the parent class doesn't have (*declare*) a copy-constructor or
assignment operator, a default compiler-generated implementation
of these functions will exist and be accessible.
(Let's call this the "copy constructor method" -- for the discussion below.)

Durn, I forgot! *blush* Yes, the parent class doesn't declare a copy
constructor, so it has the default. The default copy constructor copies
ptr values, but that's okay because we can write a little method to
allocate new memory (assigning new ptr values to our new object).

Thanks! :-)
I would stay away from memcpy. It does lead to real problems
(not only in theory, though it depends on the contents of Parent).
eg, I found that if some of the data members in Parent are NULL, then
memcpy() results in a NULL ref exception (even *if* I try to allocate
new memory to the child data members). Strange.
If you really need a hack, the following might be more
reliable:

// File: Derived.cpp
#define private public //illegal, but typically works in practice...
#include "Parent.h"
#undef private
//... other includes ...
// and use the copy-constructor of Parent,
// as suggested in my previous reply


(Let's call this the "macro hack method" -- for the discussion below.)

Ah, yes, defining keywords as macros. (I just saw that done for "new"
somewhere.) ;-) Dangerous if someone tries to use class Derived in with
*precompiled* Parent code, I'd think (because then the "private" macro
wouldn't have been defined when Parent was compiled).

-------//-------

FYI, below is my complete test program, hacks and all. Only the copy
constructor method (and the macro hack method) is 100% reliable. I have
no questions. :-)
--Suzanne

#include <iostream>

#define COUT std::cout
#define FLUSH std::flush

#define private public //----- BEGIN HACK -----

class Parent
{
private:
int* mX;
protected:
int* mY;
public:
int* mZ;
public:
Parent(int* x=NULL, int* y=NULL, int* z=NULL) : mX(x), mY(y), mZ(z)
{
if (mX==NULL) mX = new int(3);
if (mY==NULL) mY = new int(5);
if (mZ==NULL) mZ = new int(7);
}
virtual ~Parent() { delete mX; delete mY; delete mZ; }

void print() { COUT << "(" << mX << ", " << mY << ", " << mZ << ")\n"
<< "(" << *mX << ", " << *mY << ", " << *mZ <<
")\n----------------\n" << FLUSH; }
};

#undef private //----- END HACK -----

class Derived : public Parent
{
public:
Derived() {}
//*************** *************** *************** *************** *************
// WORKS

//*************** *************** *************** *************** *************
Derived(Parent& rhs) : Parent(rhs) { fixupPtrs(); }

//*************** *************** *************** *************** *************

Derived& copy1(Parent& p) // WARNING: Works here iff ptrs are
non-NULL -- but undefined in general
{
memcpy(this, static_cast<Der ived*>(&p), sizeof(Derived) );
fixupPtrs();
return *this;
}
Derived& copy2(Parent& p) // WARNING: Works here iff ptrs are
non-NULL -- but undefined in general
{
memcpy(static_c ast<Parent*>(th is), &p, sizeof(Parent)) ;
fixupPtrs();
return *this;
}
Derived& copy3(Parent& p) // WARNING: Works here iff "private" is
macro #define'd as "protected" or "public"
{
Derived& d = static_cast<Der ived&>(p);
mX = d.mX!=NULL ? new int(*(d.mX)) : new int(3);
mY = d.mY!=NULL ? new int(*(d.mY)) : new int(5);
mZ = d.mZ!=NULL ? new int(*(d.mZ)) : new int(7);
return *this;
}
Derived& copy4(Parent& p) // WARNING: Senseless crap -- and
sometimes gives NULL ref exception!!
{
const_cast<Deri ved*>(this) = &(Derived(p) );
fixupPtrs();
return *this;
}

private: // Give this object different ptrs from (but the same values
as) the parent from which it was copied
void fixupPtrs() { mX = new int(*mX); mY = new int(*mY); mZ = new
int(*mZ); }
};

int main(int argc, char** argv)
{
Parent* p = new Parent();
Derived* d = new Derived();

COUT << "//////////////////////// Parent: ///////////////////////\n";
p->print();

// ----- All of these are *unsafe* -----
COUT << "//////////////////////// Derived: ///////////////////////\n";
d->copy1(*p).prin t();
d->copy2(*p).prin t();
d->copy3(*p).prin t();
//d->copy4(*p).prin t(); // Yeeks, gives NULL ref exception

// ----- This is *safe* -----
COUT << "//////////////////////// Derived: ///////////////////////\n";
Derived* d2 = new Derived(*p);
d2->print();

delete p;
delete d;
delete d2;
}

Jul 22 '05 #5
>> // File: Derived.cpp
#define private public //illegal, but typically works in practice...
#include "Parent.h"
#undef private
//... other includes ...
// and use the copy-constructor of Parent,
// as suggested in my previous reply
(Let's call this the "macro hack method" -- for the discussion below.)

Ah, yes, defining keywords as macros. (I just saw that done for "new"
somewhere.) ;-) Dangerous if someone tries to use class Derived in with
*precompiled * Parent code, I'd think (because then the "private" macro
wouldn't have been defined when Parent was compiled).


Public, private and protected qualifiers are compile-time only;
--i.e.: they are not retained in (compiled) object code.
#define private public //----- BEGIN HACK -----

class Parent
{ ....(snip)...};

#undef private //----- END HACK -----


The above will indeed affect other code using the base class. Do the
hack in the derived class header file:

//-----------------------------------------------
#define private protected //----- BEGIN HACK -----
#include "parent.h"
#undef private //----- END HACK -----

class Derived : public Parent
{
...
};
//-----------------------------------------------
But given that you said that the parent class has its compiler default
copy constructor intact; I don't see the need to hack it in the first
place...

Jul 22 '05 #6

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

Similar topics

5
2413
by: Sandeep | last post by:
Hi, In the following code, I wonder how a private member of the class is being accessed. The code compiles well in Visual Studio 6.0. class Sample { private: int x; public:
2
2309
by: Steven T. Hatton | last post by:
I find the surprising. If I derive Rectangle from Point, I can access the members of Point inherited by Rectangle _IF_ they are actually members of a Rectangle. If I have a member of type Point in Rectangle, the compiler tells me Point::x is protected. I would have expected Rectangle to see the protected members of any Point. Compiling the following code give me this error: g++ -o rectangle main.cc main.cc: In member function `size_t...
2
3911
by: yccheok | last post by:
hello, in a singleton design, i trying to make my parent class having protected constructor and destructor. however, the compiler give me error when my child, trying to delete itself through parent pointer. isn't child should have access to parent protected destructor? thank you. class CMachineFactory
7
7261
by: TT (Tom Tempelaere) | last post by:
Hi there The line marked *** doesn't compile. I wonder why the designers of C# decided to disallow this. Rationale? Are there plans to change this? This feature forces me to make things public when the operations are in fact protected. This breaks a lot of patterns for me public class C public void F( C other) this.G() other.G(); // **
11
3836
by: Kevin Prichard | last post by:
Hi all, I've recently been following the object-oriented techiques discussed here and have been testing them for use in a web application. There is problem that I'd like to discuss with you experts. I would like to produce Javascript classes that can be "subclassed" with certain behaviors defined at subclass time. There are plenty of ways to do this through prototyping and other techniques, but these behaviors need to be static and...
16
3625
by: Fir5tSight | last post by:
Hi All, I have a small C#.NET program that is as follows: using System; class A { protected int x = 123; }
15
3084
by: =?Utf-8?B?R2Vvcmdl?= | last post by:
Hello everyone, I met with a strange issue that derived class function can not access base class's protected member. Do you know why? Here is the error message and code. error C2248: 'base::~base' : cannot access protected member declared in
12
4820
by: Robert Fuchs | last post by:
Hello, This example: public class BaseC { public int x; public void Invoke() {} } public class DerivedC : BaseC
8
2593
by: Mayur H Chauhan | last post by:
All, For my knowledge, if I declare Class as follow, then it thows compilation error. Protected Class Book End Class Even same for...
0
8801
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
8707
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,...
0
9174
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 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...
0
9015
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7953
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5947
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();...
1
3158
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
2520
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2110
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.