开发者

c++ protected pointer member to the same class and access privileges

Example code is included at the bottom of the message. I'm puzzled about the protected access specifier in a class. I have define a class node which has a protected string member name

string name;

and a vector of node pointers

vector args;

Before I thought that a member function of node could not do

args[0]->name

but a program that does just this does compile and run. However, now I would like to inherit this class and access the name field in one of the args array pointers from this derived class

args[0]->name

but this does not compile. When I compile the example code below with the commented sections uncommented, the compiler reports:

Compiler output:

g++ test.cc -o test

test.cc: In member function 'void foo::newnode::print_args2()':

test.cc:22: error: 'std::string foo::node::name' is protected

test.cc:61: error: within this context

Compilation exited abnormally with code 1 at Thu Jun 17 12:40:12

Questions:

  1. Why can I access the name field of the node pointers in args in class node, because this is what I would excpect from a similarly defined private field in Java.

  2. How can I access those fields from the derived class.

Example code:

    #include <iostream>
#include <vector>

using namespace std;

namespace foo
{
  class node;
  typedef std::vector<node*> nodes;

  class node
  {
  public:
    node (string _name);


    void print_args ();
    void add_node (node* a);

  protected:
    nodes args;
    string name;

  };
}

foo::node::node (string _name)
  : args(0)
{
  name = _name;
}

void foo::node::add_node (node* a)
{
  args.push_back(a);
}

void foo::node::print_args ()
{
  for (int i = 0; i < args.size(); i++)
  {
    cout << "node " << i << ": " << args[i]->name << endl;
  }
}

// namespace foo
// {
//   class newnode : public node
开发者_StackOverflow//   {
//   public:
//     newnode (string _name) : node(_name) {}
//     void print_args2 ();
//   protected:
//   };
// }

// void foo::newnode::print_args2 ()
// {
//   for (int i = 0; i < args.size(); i++)
//   {
//     cout << "node " << i << ": " << args[i]->name << endl;
//   }
// }

int main (int argc, char** argv)
{
  foo::node a ("a");
  foo::node b ("b");
  foo::node c ("c");
  a.add_node (&b);
  a.add_node (&c);
  a.print_args ();

  // foo::newnode newa ("newa");
  // foo::newnode newb ("newb");
  // foo::newnode newc ("newc");
  // newa.add_node (&newb);
  // newa.add_node (&newc);
  // newa.print_args2 ();

  return 0;
}


The compiler will allow that an object A accesses private/protected members of an object B if A and B have the same static type.

I will try to make this clear with an example:

class Base
{
    protected:
        int a;
};

class Derived : public Base
{
    public:
        void foo(Base& b, Derived& d)
        {
            //allowed because this obviously has the same type as this :)
            a = 1;
            //allowed because this has the same type as d (Derived)
            d.a = 1;
            //not allowed because this (Derived) does not have the same
            //type as b (Base). They might have the same dynamic type
            //but the compiler has no way of knowing this.
            b.a = 1;
        }
};

So, to answer your questions:

  1. Class node is allowed to access the name field if the node pointers of your args vector because they are also of class node.
  2. You cannot directly. You either have to make the field public (I wouldn't do that) or make public accessors.


Hm.. I'll try to explain:)

The problem is in the way you're accessing the name variable: trough the node object and not from the newnode class as you expecting. Possible solution would be that you add an getter method for the name variable:

cout << "node " << i << ": " << args[i]->GetName() << endl;

GetName() should be placed in the node class and can look like following:

std::string GetName() const
{
    return name;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜