Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Problem with a friend declaration when migrating project

Reply
Thread Tools

Problem with a friend declaration when migrating project

 
 
Uwe Kotyczka
Guest
Posts: n/a
 
      08-23-2012
When migrationg a project from Visual Studio 2003 to Visual Studio
2010 I found a problem with a friend declarition. To illustratte it
I wrote a small sample programm (complete code see below).

I have two classes, class A and class Property. Class Property has
an assignment operator: const Property& operator=(const double
dValue);

Class A has a member variable of type Property. Only in one
specific function of class A, say A:oSetProperty, I want
that the property can be changed. Therefore I declared the
assignment operator of class Property private and made
A:oSetProperty a friend function of class Property.

That worked fine in Visual Studio 2003, however when migrating
to Visual Studio 2010 the compiler complains that it can't
see the friend declaration of A:oSetProperty, because
A:oSetProperty is protected in class A.

As a workaround I can either make A:oSetProperty public
(which is not what I want to do) or declare the complete
class A as a friend of class Property (which I do not wish
to do either). Or I make the assignment operator public,
but then it can be called in any function of class A and
not only in A:oSetProperty.

What would be the best solution? I would prefer a clear design
over a workaround.

Here comes the complete sample code:


#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>

////////////////////////////////////////////////////////////
class Property;

////////////////////////////////////////////////////////////
class A
{
public:
A();
virtual ~A();
void SetProperty(const double dValue);
protected:
void DoSetProperty(const double dValue);
private:
Property* m_pProperty;
};

////////////////////////////////////////////////////////////
class Property
{
friend void A:oSetProperty(const double dValue);
public:
Property();
virtual ~Property();
int GetValue() const;
private:
const Property& operator=(const double dValue);
int m_nValue;
};

////////////////////////////////////////////////////////////
A::A()
{
m_pProperty = new Property();
}

A::~A()
{
if (m_pProperty)
delete m_pProperty;
}
void A::SetProperty(const double dValue)
{
DoSetProperty(dValue);
}

void A:oSetProperty(const double dValue)
{
if (m_pProperty)
*m_pProperty = dValue;
}

////////////////////////////////////////////////////////////
Property:roperty()
{
m_nValue = -1;
}

Property::~Property()
{
}

int Property::GetValue() const
{
return m_nValue;
}

const Property& Property:perator=(const double dValue)
{
m_nValue = static_cast<int>(dValue);
return *this;
}

////////////////////////////////////////////////////////////
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
A testA;
testA.SetProperty(5.5);

return 0;
}
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-23-2012
On 8/23/2012 6:39 AM, Uwe Kotyczka wrote:
> I have two classes, class A and class Property. Class Property has
> an assignment operator: const Property& operator=(const double
> dValue);
>
> Class A has a member variable of type Property. Only in one
> specific function of class A, say A:oSetProperty, I want
> that the property can be changed. Therefore I declared the
> assignment operator of class Property private and made
> A:oSetProperty a friend function of class Property.
>
> That worked fine in Visual Studio 2003, however when migrating
> to Visual Studio 2010 the compiler complains that it can't
> see the friend declaration of A:oSetProperty, because
> A:oSetProperty is protected in class A.
>
> As a workaround I can either make A:oSetProperty public
> (which is not what I want to do) or declare the complete
> class A as a friend of class Property (which I do not wish
> to do either). Or I make the assignment operator public,
> but then it can be called in any function of class A and
> not only in A:oSetProperty.
>
> What would be the best solution? I would prefer a clear design
> over a workaround.


You have a chicken and egg design problem. On one hand, your property
requires friendship to use its operator=. So, you solve it by making
the user of operator= (your 'A:oSetProperty' function) a friend of
Property. On the other hand, access to 'A:oSetProperty' is blocked as
well, so you need to give your Property some way to access it. You can
make Property a *derived class* of A, but that's not right, is it?

Declare class Property a friend of A. After all, in order to see A's
private (and protected) parts, Property has to be either a friend or a
relative. Another possibility is to get rid of the extra indirection
(the 'A:oSetProperty' nonsense), leave only 'A::SetProperty' around
and let *that member* be a friend of Property. What's the reason to
have that 'DoSetProperty', anyway?

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
friend does not match any template declaration problem Klaus C++ 3 03-31-2008 04:24 PM



Advertisments