Consider this code:
class A
{
struct B {};
std::vector<B> _vec;
public:
const std::vector<B>& get() const { return _vec; }
};
Note that B
is private within class A
. The above code compiles, but when calling get()
from outside class A
, it does not:
const std::vector<A::B>& vec = get(); // does not compile
Indeed, A::B
is private
. However, from C++11
on, you could simply do this:
const auto& vec = get();
which works perfectly.
For the same reason as above, you cannot do the following:
A::B obj;
But, since there is a public
getter, you can deduce the type from that getter function. In this particular case, one could do:
using B = std::decay<decltype(C{}.get())>::type::value_type;
B obj;
Questions
I'm not sure how to formulate my questions. It seems strange to me that, from C++11 on (and not before), we actually can instantiate A::B
being the latter private
. And even more, I think it's strange we can call const auto& get()
. Is there any explanation for this? Wouldn't it be better not be allowed doing this? Should I declare A::B
public
? I feel like it doesn't make sense to declare it private
if you need a getter function like the one in the above code.
Fields should be declared private unless there is a good reason for not doing so. One of the guiding principles of lasting value in programming is "Minimize ripple effects by keeping secrets." When a field is private , the caller cannot usually get inappropriate direct access to the field.
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass. A nested class has access to all the private members of its enclosing class—both fields and methods.
The error "Property is private in type 'X' but not in type 'Y'" occurs when the visibility of a property is changed when a class extends another or implements an interface. To solve the error, use a setter and a getter with custom logic that suits your use case.
TypeScript Private PropertiesUsing TypeScript, we can add private functionality into our classes. What are private properties or methods? A private property of method can only be accessed or called from the class instance itself.
It seems strange to me that, from C++11 on (and not before), we actually can instantiate A::B being the latter private.
You could do it in C++98/03 just fine, through template argument deduction:
template<typename T>
void temp_func(const T &t)
{
...
T u = t;
}
temp_func(a.get()); //Will use the private type.
You can even use T
inside of temp_func
.
Making a type private was never a guarantee of making the type inaccessible from the outside. Private has always refer to the accessibility of the name, not of the construct behind the name. If you want a type to only be used within a scope, then that typename cannot be part of any non-private interfaces. And this has always been the case.
Should I declare
A::B
public?
That's up to you. However, if you expose a public user interface, you are making a statement that the user can, you know, use the interface. In order for the user to know how to use a vector<A::B>
, they have to know how A::B
behaves. So they have to use its definition. Even though it's private.
So if a user has to know about a type and about how a type behaves... is it really "private"?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With