1

With a friend, we had following problem recently. There was a base class:

class A {
public:
    A() : foo(10) {}
    virtual int getFoo() const { return foo; }

protected:
    int foo;
};

A friend implemented a class deriving from the one above.

class B : public A {
public:
    void process() { foo = 666; }
protected:
    //int foo;
};

Unfortunatelly he also added field foo in descendent class (commented line). So the following code.

#include <iostream>

int main()
{
    A* aaa= NULL;
    if (1) {
        B* bbb = new B;
        bbb->process();
        aaa = bbb;
    }

    std::cout << aaa->getFoo() << std::endl;

    return 0;
}

printed 10.

That's not the problem, since this will be totally redesigned, and such things won't happen in future.

I was just wondering, do you know any (portable) tricks or language patterns (besides obvious getters/setters; btw they were there actually, with foo being private), that would disallow declaring variable with the same name in descendent class (e.g. by causing compile-time error).

TIA!

GiM
  • 460
  • 4
  • 13
  • foo isn't private in the code, it is protected which is an entirely different thing – Patrick Jul 28 '10 at 15:59
  • AFAIK that's not possible. Expect to read a lot about inheriting protected members isn't that great idea :o) I can only recommend Lint to detect these cases... – MaR Jul 28 '10 at 16:05
  • `protected` can develop into a can of worms. Use it cautiously. Usually, `public` or `private` will do whatever you need done with less possible confusion. – David Thornley Jul 28 '10 at 16:23
  • Your examples leaks. At the least, delete it (and give `A` a virtual destructor), or stick it in an `auto_ptr`. Or just don't dynamically allocate. – GManNickG Jul 28 '10 at 16:43
  • the code is simplified, in reality, foo is private and has getter/setter, and yes it has virtual dtors – GiM Jul 28 '10 at 16:47
  • 1
    @GIM Always here - POST THE REAL CODE!!!!!! I really can't believe this - have a downvote from me. –  Jul 28 '10 at 16:49
  • @GiM: That doesn't make sense; the entire question is based on a protected foo, which imposes no requirements on using getters or setters. Real simplified code is a good thing, but don't remove essentials. (Then it stops being real code, but some imaginary problem.) – GManNickG Jul 28 '10 at 17:18

4 Answers4

6

No - you are not supposed to care about the implementation of the base class, so you should not be constrained in naming members in your derived class. And protected data is a bad idea.

3

You can make all your variables private then it doesn't matter if variables have the same name in descended classes, you'll always be accessing the correct variable - much better encapsulation which in turn will make your code easier to maintain in the long run.

PS : your test case does not need to be so complicated:

B b;
b.process();
b.getfoo();

will return 10 as well

Patrick
  • 8,175
  • 7
  • 56
  • 72
  • yeah I know, problem is the foo added in B was definitelly a mistake thanks for pointing out code simplication – GiM Jul 28 '10 at 16:54
1

C++ doesn't have a lot of features to protect you from mistakes. It doesn't really have any way to know what you intended and so can't tell what is really a mistake.

Jay
  • 13,803
  • 4
  • 42
  • 69
  • 4
    Actually, it has a huge number of features to protect you from mistakes - more than most other languages. But not in this case, because it is not a mistake. –  Jul 28 '10 at 16:00
0

Not in the language itself, but some compilers can be configured to report certain types of warnings as errors. Consult your compilers documentation for reference.

Axel
  • 13,939
  • 5
  • 50
  • 79