Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shouldn't access to private types be prohibited?

Tags:

c++

c++11

c++03

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.

like image 783
mfnx Avatar asked Sep 06 '19 13:09

mfnx


People also ask

Why should you make fields private and not public?

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.

Can private be accessed by subclass?

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.

Is private in type but not in type?

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.

Does TypeScript have private?

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.


1 Answers

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"?

like image 50
Nicol Bolas Avatar answered Sep 28 '22 04:09

Nicol Bolas