Access specifiers in class

If I write f.do_nothing() obviously it will give me compilation error. In this case how is access specifier resolved? All I know is how virtual function is working but I don't get how access specifier is resolved because I made the function private so even after resolving how is d or dee accessing
do_nothing().

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
33
 #include <iostream>

using namespace std;

class demo
{
public:
	void virtual do_nothing()  = 0;
};

class derived: public demo {

};

class derived_1 :public derived {
private:
	void do_nothing() {
		cout << "DO NOTHING" << endl;
	}
};

int main()
{
	derived* d = new derived_1;
	demo* dee;
	dee = static_cast<demo *>(d);
	d->do_nothing();
	dee->do_nothing();
	derived_1 f;
        	

	return 0;
}
Hello keh k lenge,

If I am wrong here someone will correct me. I believe it all comes down to inheritance. "derived_1" inherits from "derived" which inherits from "demo". If I have this correct "derived_1" would look something like this because of the inheritance:

1
2
3
4
5
6
7
8
9
10
11
12
class derived_1 : public derived
{
        //  Not actually coded here, but came from demo.
	public:
		void virtual do_nothing() = 0;

	private:
		void do_nothing()
		{
			cout << "DO NOTHING" << endl;
		}
};


So, whether "void virtual do_nothing() = 0;" is inherited from "demo" or defined in "derived_1" it works the same. That is why "d" and "dee" both print the message.

Hope that helps,

Andy
I think the function is virtual in all cases. It's just public in classes demo and derived, and private in class derived_1. This is perfectly legal although a little strange.
> I don't get how access specifier is resolved

It is very straightforward.

a. Access to a member is checked at compile time; based on the compile-time type (static type).
In dee->do_nothing(); the type of dee is 'pointer to demo'. In the class demo, the member do_nothing() is public.

b. A call to a virtual functions (selected via unqualified name lookup) is dispatched at run time, based on the run-time type (dynamic type) of the object.

c. The accessibility of an overridden virtual function need not be the same as that in the base class.


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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>

struct base
{
    public: virtual void foo() { std::cout << "public: base::foo\n" ; }
    protected: virtual void bar() { std::cout << "protected: base::bar\n" ; }
    private: virtual void baz() { std::cout << "private: base::baz\n" ; }
};

struct derived : base
{
    // override foo (public in base, private in derived)
    private: virtual void foo() override { std::cout << "private: derived::foo\n" ; }

    // override bar (protected in base, public in derived)
    public: virtual void bar() override { std::cout << "public: derived::bar\n" ; }

    // override baz (private in base, protected in derived)
    protected: virtual void baz() override { std::cout << "protected: derived::baz\n" ; }
};

struct more_derived : derived
{
    // override bar (protected in base, public in derived, private in more_derived)
    private: virtual void bar() override { std::cout << "private: more_derived::bar\n" ; }
};

int main()
{
    more_derived more_d ;
    derived& dee = more_d ;
    base& bee = more_d ;

    bee.foo() ; // fine: base::foo is public
                // calls private: derived::foo

    // dee.foo() ; // *** error ***: derived::foo is private


    // bee.bar() ; // *** error ***: base::bar is protected

    dee.bar() ; // fine: derived::bar is public
                // call private: more_derived::bar

    // more_d.bar()  ; // *** error ***: more_derived::bar is private

    more_d.derived::bar() ; // fine: derived::bar is public
                            // qualified name, so no run-time dispatch
                            // call public: derived::bar
}

http://coliru.stacked-crooked.com/a/d2b43f5d1dbf25b8
Topic archived. No new replies allowed.