|
-
October 23rd, 2004, 03:29 AM
#1
copy construct
HI!
I need to realize a didactic application, with a CFigure base class and 4 derivate classes: CLine, CTriangle, CCircle and CRectable.
The base clase (CFigure has 2 private special attributes:
CPen m_LineColor;
CBrush m_FillColor and the derivated classes acccess it throught public metods.
But, I have problems to the Set and Get methods of this classes.
CPen CFigure::GetLineColor()
{
EXTLOGPEN extlogpen;
m_LineColor.GetExtLogPen( &extlogpen );
return m_LineColor; //!!! Error HERE
}
Error: C2558: class Pen no copy constructor available
I build 2 constructors, a simple constructor and one with parameters.
CFigure::CFigure()
{
m_strFigName = _T("");
m_iX1 = 0;
m_iY1 = 0;
EXTLOGPEN extlogpen;
CPen line_col;
line_col.GetExtLogPen( &extlogpen );
LOGBRUSH LogBrush = { extlogpen.elpBrushStyle, extlogpen.elpColor, extlogpen.elpHatch };
m_LineColor.CreatePen( extlogpen.elpPenStyle, extlogpen.elpWidth, &LogBrush );
LOGBRUSH logbrush;
CBrush fill_col;
fill_col.GetLogBrush( &logbrush );
m_FillColor.CreateBrushIndirect(&logbrush);
}
CFigure::CFigure(int coordX, int coordY, CPen& line_col, CBrush& fill_col, CString figName)
{
m_strFigName = figName;
m_iX1 = coordX;
m_iY1 = coordY;
EXTLOGPEN extlogpen;
line_col.GetExtLogPen( &extlogpen );
LOGBRUSH LogBrush = { extlogpen.elpBrushStyle, extlogpen.elpColor, extlogpen.elpHatch };
m_LineColor.CreatePen( extlogpen.elpPenStyle, extlogpen.elpWidth, &LogBrush );
LOGBRUSH logbrush;
fill_col.GetLogBrush( &logbrush );
m_FillColor.CreateBrushIndirect(&logbrush);
}
CFigure::~CFigure()
{
m_LineColor.DeleteObject();
m_FillColor.DeleteObject();
}
What can I do to access this base class atribute (ex. m_LineColor)?
-
October 23rd, 2004, 07:50 AM
#2
Re: copy construct
Your GetLineColor() routine wants to return a CPen object, but the compiler doesn't have the information it needs to copy a CPen object onto the stack, hence the error message. Copy constructors generally have the form, for example, CMyPen( const CMyPen &source_of_data ), and copy required data members from source_of_data to the invoking object.
Do a search for "copy constructor" in MSDN, and have a look at the articles. You can either write your own class based on CPen and include a copy constructor, or you can sidestep the whole problem and make m_LineColor public.
Regards
Robert Thompson
-
October 23rd, 2004, 08:06 AM
#3
Re: copy construct
When returning from CFigure::GetLineColor, a copy of m_LineColor must be made. But, as compiler sais, class CPen has no copy constructor. You have a choice to derive from CPen and define a copy constructor, as TSYS already said.
Better is to return a reference from Get functions.
See next example:
Code:
class CFigure
{
// ...
// Attributes
protected:
CPen m_pen;
// Operations
public:
// CPen GetPen1() {return m_pen;} // no copy constructor available
CPen& GetPen2() {return m_pen;}
const CPen& GetPen3() const {return m_pen;}
};
By the way... You really are Maximus Decimus Meridius, Commander of the Armies of the North, General of the Felix Legions, loyal servant to the true emperor, Marcus Aurelius. Father to a murdered son, husband to a murdered wife. ?
Last edited by ovidiucucu; October 23rd, 2004 at 08:10 AM.
-
October 23rd, 2004, 08:34 AM
#4
Re: copy construct
More to discuss here because your problem sounds like a quiz.
Declaring private members in base class and accessing them in derived classes throught public metods it's like
scratching yourself on the right side of head using the left hand. 
Just declare them as protected, is there a problem for you to do this?
-
October 23rd, 2004, 11:10 AM
#5
Re: copy construct
I have to disagree with ovidiucucu on this one. Returning a reference to an internal (aggregated) item is risky when there is no object managment involved.
If CFigure object goes out of scope, then the CPen object will be destroyed also. However there may be outstanding references (via ovidiucucu's suggestion). This will most likely lead to a crash or other undefined behaviour.
Scott Meyers has a full chapter (#23) devoted to this subject if you are looking for an indepth discussion.
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
October 24th, 2004, 05:21 AM
#6
Re: copy construct
 Originally Posted by TheCPUWizard
I have to disagree with ovidiucucu on this one. Returning a reference to an internal (aggregated) item is risky when there is no object managment involved.
If CFigure object goes out of scope, then the CPen object will be destroyed also. However there may be outstanding references (via ovidiucucu's suggestion). This will most likely lead to a crash or other undefined behaviour.
Scott Meyers has a full chapter (#23) devoted to this subject if you are looking for an indepth discussion.
At last, everithing is risky more or less. Because I'm not the first or the last suggesting (or implementing) that, you and Mr. Scott Meyers will have a lot to fight...
Do you think it's so difficult for a programmer to understand that keeping and using that reference to CPen after CFigure goes out of scope it's not good? Anyhow it's less probable to do that mistake.
Come on, let theoreticians write books and us continue programming.
Anyhow, you can read again my second post to see that the solution of OP is much more easier.
Last edited by ovidiucucu; October 24th, 2004 at 07:10 AM.
-
October 24th, 2004, 08:33 AM
#7
Re: copy construct
Thanks to everyone!
The problem was slove by me and I found a new other solution.
This subject is CLOSE.
-
October 24th, 2004, 08:36 AM
#8
Re: copy construct
As a professional developer I see the problem (using an obsolete/invalid reference) occur in the real world an average of 4-6 times a year. This does not could all of the times where the programmer having an "unexplained crash" or other strange behaviour finds the problemn himself!
Since a good number of hours (therefore $) are spend before I am called in, this indicates a fairly high real world cost related to returning references when you really need to return objects!
Of course if there is a method for tracking object usage (e.g. Reference Counting like COM), then you can pass references safely and freely, provided you always uuse the right type to hold the reference!
You are quote correct that the OP should make the PEN available to the derived classes using a much simpler technique. It is a tradeoff between making the CPEN itself a protected member or providing a protected accessor. I prefer the use of an accessor to remain consistant with the "data is private" paradigm and pure encapsulation.
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
October 24th, 2004, 09:12 AM
#9
Re: copy construct
 Originally Posted by TheCPUWizard
As a professional developer I see the problem (using an obsolete/invalid reference) occur in the real world an average of 4-6 times a year.
"There are three types of lies - lies, damned lies, and statistics"
I prefer the use of an accessor to remain consistant with the "data is private" paradigm and pure encapsulation.
If you meet the perfect woman, I can tell, you'll don't like: she does not allow you all you wish. 
This is one reason programmers love C++: it's not pure OO.
The pure OOP lovers can try Java, Smalltalk and so on...
-
October 25th, 2004, 02:29 AM
#10
Re: copy construct
 Originally Posted by ovidiucucu
Just declare them as protected, is there a problem for you to do this?
Protected is just as bad as public if you worry about breaking encapsulation.
 Originally Posted by ovidiucucu
This is one reason programmers love C++: it's not pure OO.
The pure OOP lovers can try Java, Smalltalk and so on...
And then again not everything in Java in an object, in pureOO spirit, for instance primitive types (int, float, double, etc.) ar not.
-
October 25th, 2004, 04:14 AM
#11
Re: copy construct
 Originally Posted by cilu
And then again not everything in Java in an object, in pureOO spirit, for instance primitive types (int, float, double, etc.) ar not.
Then enjoy with Smalltalk where True is a class having (among others) a wonderful method IsTrue returning self. (something similar with this).
Hokutata Yakubotu
-
October 25th, 2004, 04:36 AM
#12
Re: copy construct
Yes, I know. That was my point.
-
October 25th, 2004, 04:57 AM
#13
Re: copy construct
 Originally Posted by cilu
Protected is just as bad as public if you worry about breaking encapsulation.
Well, not quite as bad . If a derived class gains a reference to an aggregated entity (either by an accessor or directly to the data), there is no issue of the actual object going out of scope before the reference as the derived class will always be destroyed before the base class. This is not true if other objects perform the same type of operation where order of destruction can not be known (by the designer of the base class in question).
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
October 25th, 2004, 09:18 AM
#14
Re: copy construct
 Originally Posted by TheCPUWizard
I have to disagree with ovidiucucu on this one. Returning a reference to an internal (aggregated) item is risky when there is no object managment involved.
If CFigure object goes out of scope, then the CPen object will be destroyed also. However there may be outstanding references (via ovidiucucu's suggestion). This will most likely lead to a crash or other undefined behaviour.
Scott Meyers has a full chapter (#23) devoted to this subject if you are looking for an indepth discussion.
Code:
class CFufu
{
public:
CFufu() : m_strFufu(_T("FUFU")) {}
private:
CString m_strFufu;
};
class CFu
{
private:
CFufu m_fufu;
public:
CFufu& GetFufu() {return m_fufu;}
};
Please, give us one simple example how to make a reference to a CFufu object initializated via CFu::GetFufu(), that can be used after CFu object goes out of scope (refer to an invalid CFufu object, so generates a dangerous situation).
Last edited by marsh_pottaye; October 25th, 2004 at 09:25 AM.
-
October 25th, 2004, 12:57 PM
#15
Re: copy construct
Code:
CFu *p = new CFu();
CFuFu &r = p->GetFuFu();
delete p;
// r is now invalid
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|