question about "protected" member functions and derived class access

I don't agree with the compiler that what I'm doing is an error:

in dma.h
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
 class abstractDMA
{
private:
	char* label;
	int rating;
protected:
	const char* Label() {return label;}
	const int Rating() {return rating;}
public:
	abstractDMA(const char* l = "null", int r = 0);
	virtual ~abstractDMA();
	abstractDMA& operator=(const abstractDMA& rs);
	friend std::ostream& operator<<(std::ostream& os, const abstractDMA& rs);
	virtual void View() = 0;
};



class lacksDMA : public abstractDMA
{
private:
	enum {COL_LEN = 40};
	char color[COL_LEN];
public:
	lacksDMA(const char* c = "blank", const char* l = "null", int r = 0);
	lacksDMA(const char* c, const abstractDMA& rs);
	friend std::ostream& operator<<(std::ostream& os, const lacksDMA& rs);
	void View();
};


in dma.cpp
1
2
3
4
5
lacksDMA::lacksDMA(const char* c, const abstractDMA& rs) : abstractDMA(rs.Label(), rs.Rating())
{
	strncpy(color, c, COL_LEN - 1);
	color[COL_LEN - 1] = '\0';
}


part of the compiler error:
dma.h: In constructor ‘lacksDMA::lacksDMA(const char*, const abstractDMA&)’:
dma.h:49:14: error: ‘const char* abstractDMA::Label()’ is protected
dma.cpp:52:81: error: within this context
dma.cpp:52:81: error: passing ‘const abstractDMA’ as ‘this’ argument of ‘const char* abstractDMA::Label()’ discards qualifiers [-fpermissive]


I've never used the "protected" keyword before but I thought I should be able to use those functions in the derived lacksDMA class. Help plz :(
The protected members form the special class interface for the member functions of the derived type. This is different from the public interface, which is formed by non-member functions in the same namespace and public members, and one of the differences is that protected members are *not* accessible through abstractDMA itself; only through classes that are derived from it.

Compare:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Base {
 protected:
    int i;
};

struct Derived : Base {
    void f(Base& b, Derived& d)
    {
        ++b.i; // error
        ++d.i; // okay
        ++i; // okay
    }
};

clang++ says:
test.cc:9:13: error: 'i' is a protected member of 'Base'
        ++b.i; // error
            ^
test.cc:3:9: note: can only access this member on an object of type 'Derived'
    int i;
        ^
Last edited on
protected members are *not* accessible through abstractDMA itself

Book neglected to mention this. Thanks.
well, member functions and friends of abstractDMA itself can access them, but once you step outside of abstractDMA, you need to be handling an object of a derived type.
well, member functions and friends of abstractDMA itself can access them, but once you step outside of abstractDMA, you need to be handling an object of a derived type.
Who the ____ decided that that should be so? Why not either always have access to protected members or never have access to them?

Guessing some technical reason that's beyond me but this just seems confusing and illogical.
It simply structures access like so:
private  : class, friends
protected : class, friends, derived classes
public   : class, friends, derived classes, everyone else
I think it's too permissive actually, I'd only allow access from the same class and through the current object in the derived class (that is, I'd reject line 10 in my example), but of course member access doesn't know object identities, it's decided on types alone.
Topic archived. No new replies allowed.