Private members and copy constructors

F

Full Decent

aclass A, B;

Can A access B's privates all the time, or only in a copy constructor?

-------and---------

This code:

#include <iostream>
class A
{
int my;
public:
A():my(0){}
void print(){std::cout<<my<<std::endl;}
void test(A x){x.my++;}
};

int main()
{
A a, b;
a.test(b);
a.print();
b.print();
}

Produces "0 0" when run.

Expected "0 1" or compile error.

--------------------

Please tell me this is one of those staying-up-late mistakes :)

Thanks,
Will
 
V

Victor Bazarov

Full said:
aclass A, B;

Can A access B's privates all the time, or only in a copy constructor?

All the time.
-------and---------

This code:

#include <iostream>
class A
{
int my;
public:
A():my(0){}
void print(){std::cout<<my<<std::endl;}

I strongly recommend rewriting it at least as

void print(ostream& os) const { os << my; }
void test(A x){x.my++;}

Passing an object by value makes a _copy_. Changing that _copy_
inside the function has no effect (in your case) on the object
from which the copy was made. Pass it by reference:

void test(A& x) { x.my++; }
};

int main()
{
A a, b;
a.test(b);
a.print();
b.print();

And doing here

a.print(std::cout); std::cout << std::endl;
b.print(std::cout); std::cout << std::endl;
}

Produces "0 0" when run.

Rightfully so.
Expected "0 1" or compile error.

I wouldn't.

Or one of those I-don't-understand-the-difference-between-passing-
by-value-and-passing-by-reference mistakes...

V
 
P

Peter Julian

Full Decent said:
aclass A, B;

Can A access B's privates all the time, or only in a copy constructor?

What B?
-------and---------

This code:

#include <iostream>
class A
{
int my;
public:
A():my(0){}
void print(){std::cout<<my<<std::endl;}
void test(A x){x.my++;}
};

test() creates a local instance of class A called x using a pass_by_value /
copy ctor.
int main()
{
A a, b;
a.test(b);
a.print();
b.print();
}

Produces "0 0" when run.

Expected "0 1" or compile error.

No, instance b was never modified in any way. Only a local copy in test was
modified.
--------------------

Please tell me this is one of those staying-up-late mistakes :)

Thanks,
Will

Try:

#include <iostream>

class A
{
int n;
public:
A():n(0) {}
void print() const {std::cout << n << std::endl;}
void test() {n++;}
};

int main()
{
A a, b;
a.test();
b.test();
a.print();
b.print();
}
 
F

Full Decent

I can't believe I made this mistake in the original code and still
passed by value in this dumb example.

Luckily you saved me and I can stay up later to make dumber mistakes.
 
F

Full Decent

Peter, the idea was to do this:

#include <iostream>
class A
{
int my;
public:
A():my(0){}
void print(){std::cout<<my<<std::endl;}
void test(A& x){x.my++;}

};

int main()
{
A a, b;
a.test(b);
a.print();
b.print();
}

This code proves that a can modify b's private parts. I wasn't sure if
this was allowed.
 
R

Ram

This code proves that a can modify b's private parts. I wasn't sure if
this was allowed.

The access restrictions apply on a per class basis and not on a per
object one. So objects belonging to the same class can always access
each other's members whether public, protected or private..

-Ramashish
 
V

Vijai Kalyan

I wouldn't think all the time. Consider the following code:

template<class T>
class Foo
{
int x;
public:
template<class C> Foo(const Foo<C>& src)
{
x = src.x;
}
};

I don't think you will be allowed to access src's privates. I guess
that is because a generic class is really a standin for a new type?
 
V

Victor Bazarov

Vijai said:
I wouldn't think all the time. Consider the following code:

template<class T>
class Foo
{
int x;
public:
template<class C> Foo(const Foo<C>& src)
{
x = src.x;
}
};

I don't think you will be allowed to access src's privates. I guess
that is because a generic class is really a standin for a new type?

That's correct. Unless 'C' is the same as 'T', 'Foo<C>' is not the
same type as 'Foo<T>'. Another twist here: the templated "copy-
constructor" cannot replace or even overload the "true" copy-c-tor,
generated in this case by the compiler for the Foo<T> class when it
is instantiated. So, no matter what, inside the constructor template
'C' will simply _never_ be the same as 'T'. Weird, eh?

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top