Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ private nested class - access to different functions

Tags:

c++

private

class

Found this strange compilation behavior, checked on VS2012, VS2017 and https://www.onlinegdb.com/online_c++_compiler)

Basically for private nested classes you can call public functions outside, but not public constructors.

3 questions:

  • what is the reasoning behind compiler letting me call func()?

  • if compiler lets me call func(), why I cannot call ctor?

  • if I cannot call ctor, how come emplace_back is able to do it?


class Outer {
    struct PrivateInner {
        PrivateInner() {}
        void func() {}
    };
public:
    PrivateInner inner;
    std::vector<PrivateInner> innerVect;
};

void f1()
{
    Outer c;
    c.inner.func(); // COMPILING, but why?
}

void f2()
{
    Outer c;
    c.innerVect.push_back(Outer::PrivateInner()); // NOT COMPILING, why no access to ctor if there is access to func()?
    c.innerVect.emplace_back(); // COMPILING, but why? Doesn't it call Outer::PrivateInner inside?
}

As I see I still can create a (static) function createObject():

class Outer {
    struct PrivateInner {
        PrivateInner() {}
        static PrivateInner createObject() { return PrivateInner(); }
        void func() {}
    };
.....
};

and then call it.

createObject() may be non-static if calling static from instances is not pure standard thing.

c.innerVect.push_back(c.inner.createObject()); // COMPILING

to "hack" compilation

like image 637
Alek86 Avatar asked Feb 02 '18 15:02

Alek86


People also ask

Can nested classes access private members?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.

How do I access private nested classes?

Accessing the Private Members Write an inner class in it, return the private members from a method within the inner class, say, getValue(), and finally from another class (from which you want to access the private members) call the getValue() method of the inner class.

What is a nested class how can we access members of a nested class?

A nested class is a class which is declared in another enclosing class. A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed.

Can nested classes access private members C#?

A nested type has access to all of the members that are accessible to its containing type. It can access private and protected members of the containing type, including any inherited protected members.


1 Answers

Note that the nested struct PrivateInner is declared as private, so only Outer::PrivateInner is private, you can't use this name to declare variable like Outer::PrivateInner pi; without sufficient access right, but you can write it like decltype(Outer::inner) pi;.

On the other hand, its constructor and member function are public, so they can be called.

c.inner.func(); // COMPILING, but why?

func() is public, so if you have got an instance of type Outer::PrivateInner you can call func on it.

c.innerVect.push_back(Outer::PrivateInner()); // NOT COMPILING, why no access to ctor if there is access to func()?

It has nothing to do with the constructor, you just can't use the name Outer::PrivateInner here.

c.innerVect.emplace_back(); // COMPILING, but why? Doesn't it call Outer::PrivateInner inside?

The constructor is public, then it could be used to construct the object. std::vector doesn't use the name like Outer::PrivateInner directly; it uses the name specified as the template argument.

BTW: For the same reason,

c.innerVect.push_back(c.inner.createObject()); // COMPILING

but c.innerVect.push_back(Outer::PrivateInner::createObject()); won't compile.

like image 107
songyuanyao Avatar answered Sep 23 '22 17:09

songyuanyao