Accessing protected fields in subclass?

Discussion in 'C++' started by carl, Mar 1, 2010.

  1. carl

    carl Guest

    I have a base class with a protected field. I have created a subclass where
    I would like to access and use this protected field:


    // Base class
    class R {
    protected:
    std::string image_path;
    };


    // Subclass
    class L : public R {
    public:
    void test(){
    std::cout << image_path << std::endl;
    }

    };

    But that is a no go, it complains that the image_path field is unknown. In
    the book Accelerated C++ pp 229 it says that subclasses can see protected
    fields from the base class so what is wrong with the above?
     
    carl, Mar 1, 2010
    #1
    1. Advertising

  2. carl

    carl Guest

    "Christian Hackl" <> wrote in message
    news:hmg6ug$ld4$-september.org...
    > carl ha scritto:
    >
    >> // Base class
    >> class R {
    >> protected:
    >> std::string image_path;
    >> };
    >>
    >>
    >> // Subclass
    >> class L : public R {
    >> public:
    >> void test(){
    >> std::cout << image_path << std::endl;
    >> }
    >>
    >> };
    >>
    >> But that is a no go, it complains that the image_path field is unknown.

    >
    > The code above is correct, and even the most broken compiler should accept
    > it, so I assume you have not posted your actual code.
    >




    I use g++ 4.4.1 on Ubuntu 9.10 and the error is:

    error: 'image_path' was not declared in this scope


    I have also tried to declare test() in the base class but that does not
    help.
     
    carl, Mar 1, 2010
    #2
    1. Advertising

  3. "carl" <carl@.com> writes:

    > I have a base class with a protected field. I have created a subclass
    > where I would like to access and use this protected field:
    >
    >
    > // Base class
    > class R {
    > protected:
    > std::string image_path;
    > };
    >
    >
    > // Subclass
    > class L : public R {
    > public:
    > void test(){
    > std::cout << image_path << std::endl;
    > }
    >
    > };
    >
    > But that is a no go, it complains that the image_path field is
    > unknown. In the book Accelerated C++ pp 229 it says that subclasses
    > can see protected fields from the base class so what is wrong with the
    > above?


    11:56:20 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $cat file.cpp
    #include <string>
    #include <iostream>

    // Base class
    class R {
    protected:
    std::string image_path;
    };


    // Subclass
    class L : public R {
    public:
    void test(){
    std::cout << image_path << std::endl;
    }
    };

    int main()
    {
    return 0;
    }


    11:56:33 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $i686-pc-cygwin-g++-4.4.1 -o test file.cpp

    11:56:53 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $ls -l | grep test
    -rwxr-xr-x+ 1 Paul Bibbings None 2103026 Mar 1 11:56 test.exe

    Works for me. I would suggest that, in your *actual* code, you are
    doing something importantly different to what is suggested by the code
    you have posted here.

    Regards

    Paul Bibbings
     
    Paul Bibbings, Mar 1, 2010
    #3
  4. On 1 mar, 12:41, Christian Hackl <> wrote:
    > carl ha scritto:
    >
    >
    >
    > > "Christian Hackl" <> wrote in message
    > >news:hmg6ug$ld4$-september.org...
    > >> carl ha scritto:

    >
    > >>> // Base class
    > >>> class R {
    > >>> protected:
    > >>>   std::string image_path;
    > >>> };

    >
    > >>> // Subclass
    > >>> class L : public R {
    > >>> public:
    > >>> void test(){
    > >>>  std::cout << image_path << std::endl;
    > >>> }

    >
    > >>> };

    >
    > >>> But that is a no go, it complains that the image_path field is unknown.
    > >> The code above is correct, and even the most broken compiler should accept
    > >> it, so I assume you have not posted your actual code.

    >
    > > I use g++ 4.4.1 on Ubuntu 9.10 and the error is:

    >
    > > error: 'image_path' was not declared in this scope

    >
    > The code compiles fine even with a lower version of g++. So, again, you
    > have not posted the same code that you feed to your compiler. You
    > probably got something wrong with include files. Perhaps you are
    > including a wrong version of R which does not have any image_path field.


    Or he has a name dependent lookup failure; this would be the case if
    the class were templated.
    template<class T>
    class R
    {...};

    template<class T>
    class L : public R {
    public:
    void test(){
    // image_path is not known in scope: use 'this->image_path' instead
    std::cout << image_path << std::endl;
    }
    };

    --
    Michael
     
    Michael Doubez, Mar 1, 2010
    #4
  5. carl

    carl Guest

    "Michael Doubez" <> wrote in message
    news:...
    On 1 mar, 12:41, Christian Hackl <> wrote:
    > carl ha scritto:
    >
    >
    >
    > > "Christian Hackl" <> wrote in message
    > >news:hmg6ug$ld4$-september.org...
    > >> carl ha scritto:

    >
    > >>> // Base class
    > >>> class R {
    > >>> protected:
    > >>> std::string image_path;
    > >>> };

    >
    > >>> // Subclass
    > >>> class L : public R {
    > >>> public:
    > >>> void test(){
    > >>> std::cout << image_path << std::endl;
    > >>> }

    >
    > >>> };

    >
    > >>> But that is a no go, it complains that the image_path field is
    > >>> unknown.
    > >> The code above is correct, and even the most broken compiler should
    > >> accept
    > >> it, so I assume you have not posted your actual code.

    >
    > > I use g++ 4.4.1 on Ubuntu 9.10 and the error is:

    >
    > > error: 'image_path' was not declared in this scope

    >
    > The code compiles fine even with a lower version of g++. So, again, you
    > have not posted the same code that you feed to your compiler. You
    > probably got something wrong with include files. Perhaps you are
    > including a wrong version of R which does not have any image_path field.


    Or he has a name dependent lookup failure; this would be the case if
    the class were templated.
    template<class T>
    class R
    {...};

    template<class T>
    class L : public R {
    public:
    void test(){
    // image_path is not known in scope: use 'this->image_path' instead
    std::cout << image_path << std::endl;
    }
    };



    Thanks that solved the problem! I omitted the template declariation since I
    was trying to make as minimal an example as possible but unfortunately that
    was exactly where the error was!

    But why is it necessay to access the protected field through the this
    pointer when using templates?
     
    carl, Mar 1, 2010
    #5
  6. carl

    Robert Fendt Guest

    And thus spake "carl" <carl@.com>
    Mon, 1 Mar 2010 13:56:36 +0100:

    > Thanks that solved the problem! I omitted the template declariation since I
    > was trying to make as minimal an example as possible but unfortunately that
    > was exactly where the error was!


    This is precisely the reason why *two* people already suggested
    that the code you posted is not the code you where trying to
    compile. In such a case it is extremely helpful (i.e.,
    necessary) to post code that actually shows the problem: among
    other things, it avoids a lot of guessing. So please do so next
    time, right from the start. It also enables people to help you
    much quicker.

    > But why is it necessay to access the protected field through the this
    > pointer when using templates?


    Because in the case of templates and inheritance, the name
    lookup mechanism gets in your way. "image_path" is not marked as
    a name depending on the template parameter, so the compiler
    tries to resolve it before even trying to instantiate the
    template (and thus looking at any inherited fields).

    There is more than one way to tell the compiler that a name is a
    'dependent name', i.e. it should wait and see if it can resolve
    the name depending on the template's definition, parameters and
    base classes (if any). Using "this->" is one of the simplest
    (and it does not meddle with virtual calls and such, so it is
    usually the recommended way). You might also want to have a look
    at

    http://www.parashift.com/c -faq-lite/templates.html#faq-35.19

    Regards,
    Robert
     
    Robert Fendt, Mar 1, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brian J. Sayatovic
    Replies:
    3
    Views:
    1,563
    Chris Smith
    May 16, 2004
  2. jstorta
    Replies:
    3
    Views:
    477
    jstorta
    Feb 20, 2006
  3. Replies:
    11
    Views:
    548
    Andrew Thompson
    Jun 4, 2008
  4. S.Volkov
    Replies:
    2
    Views:
    244
    S.Volkov
    Mar 12, 2006
  5. Trans
    Replies:
    8
    Views:
    354
    Robert Klemme
    Oct 23, 2008
Loading...

Share This Page