[try Beta version]
Not logged in

 
Effective C++

Jan 19, 2015 at 8:55am
Scott meyers's Effective C++ 3rd edition, Item 25 : Consider support for a non-throwing swap.

There's a piece of code with which the author is trying to explain how to efficiently a swap pointers to implementation. Here is the code which won't compile ( as he mentions ) because the data members are private :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class WidgetImpl {                  // class for widget data;
public:                             
...
private:
int a, b, c;                        // possibly lots of data
std::vector<double> v;              // expensive to copy
...
};

class Widget {                          // class using the pimpl idiom
public:
Widget(const Widget& rhs);
Widget& operator=(const Widget& rhs)    // to copy a widget, copy its
{                                       // WidgetImpl objec.
...
*pImpl = *(rhs.pImpl);
...
}
...
private:
WidgetImpl *pImpl;                      // ptr to object with this
};                                      // Widget's data


namespace std {
template<>                          // this is a specialized version 
void swap<Widget>(Widget& a,        // of std::swap for when T is Widget
Widget& b)
{
swap(a.pImpl, b.pImpl);             // to swap Widget, swap their
}                                   // pimpl pointer;  this wont' compile because the pImpls are private
}


What got my attention was the solution he provides for this problem, which is
to provide a public swap function that does the actual swapping and have the std swap call it :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Widget {
public:
...
void swap(Widget& other)            
{
using std::swap;            // the need for this declaration is explained later in this item
swap(pImpl, other.pImpl);   // to swap Widgets, swap their pimpl pointer
}
...
};

namespace std {                 
template<>                      // revised specialization of std::swap ( point : this is complete specialization )
void swap<Widget>(Widget& a,
Widget& b)
{
a.swap(b);                      // to swap Widgets, call their swap member function
}
}


Its the following line of code that actually got my attention :
(line 7)
swap(pImpl, other.pImpl);

Am I missing something or Is he really erroneously trying to access "other"'s
private data member "pImpl" ?
Jan 19, 2015 at 9:00am
Am I missing something or Is he really erroneously trying to access "other"'s
private data member "pImpl" ?

You're missing something. It is perfectly legal to access a Widget's private data from inside a member function, whether it is this->pImpl or other.pImpl

You may want to consider how a copy constructor or assignment operator could be implemented if it was not.
Last edited on Jan 19, 2015 at 9:02am
Jan 19, 2015 at 9:27am
Thanks.
Jan 19, 2015 at 12:09pm
Objects of the same class can access each others private data, consider this contrived example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

class Dummy
{
public:
	Dummy() : x(0), y(0) {}
	void FuncShow(const Dummy &dum) const;
private:
	int x;
	int y;
};

void Dummy::FuncShow(const Dummy &dum) const
{
	cout << dum.x << "\t" << dum.y << endl; // "this" Dummy can access private members of "dum" Dummy
}


int main()
{
	Dummy dum1;
	Dummy dum2;

	dum1.FuncShow(dum2); // dum1 can access private members of dum2
}
Topic archived. No new replies allowed.