Do we need to include the scope
baseClass::statmember.methodmember();
in a call to a static member of the base class that has been inherited when we call it from inside a method of the derived class?
I see it in a code programed by other person, I try to modify it and it compiles as well without including the scope
derivedclass::methodDerived() {
statmember.methodmember();
};
Why the programmer has included in all the calls to the member the scope:: if its unnecessary? Is it a reminder of the unicity of the static member in all the objects?
Or I am wrong and the code may give different results?
I'm guessing it's because the following is allowed:
class Base
{
public:
static void foo(){}
};
class Derived:public Base
{
public:
static void foo(){}
};
Either that, or for readability. Sometimes, just because it isn't necessary doesn't mean it has no use (even if that use is readability, which is a biggie).
It would be necessary only if the base class and the derived class have a function with the same name, and you want to distinguish between them.
Otherwise it's not necessary.
Related
I need to compile something like this:
struct Base {
virtual void func1()=0;
// ...
friend void Derived::func2(Base *base);
private:
int some_private;
}
struct Derived : Base {
virtual func3()=0;
// ...
void func2(Base *child) {
std::cout << child->some_private;
}
};
But I keep getting compilation error. I tried swapping structures or declaring them first, but I can't declare Derived first (because of inheritance), and I can't declare Base first (because I need to declare friend function in Derived). What to do?
You have a few basic solutions. The most obvious is to change from private to protected. In C++, protected means subclasses have access.
You can add more public (perhaps protected) accessor methods instead.
You can forward-reference the entire Derived class and friend the entire class.
Personally, I have never felt a need to use friend methods or classes, and I don't know under what circumstances I'd have to be in before I wouldn't depend on other ways to accomplish whatever I'm trying to accomplish.
For this particular solution, I'd change the access to protected.
Here is a base class:
class Base
{
public:
int foo;
// ...
};
This class is declared in a header file that I cannot change because I don't have the rights to do so.
Here is a derived class:
class Derived : public Base
{
public:
// provide alias to Base::foo
// ...
};
Is there a way I can provide an alternate name that refers to Base::foo inside class Derived without using pointers or references?
In other words, is there any way to provide an alias without adding any extra class members to Derived?
Also, if conditional compilation directives can be avoided, that would be ideal.
No, there is no renaming feature (though there was some work done on such a feature in the early days but it was dropped).
There's no way to do what you want other than adding the desired name as a member to Derived, and forwarding it to the base class function. Note however that this can be inline and should be absorbed by the compiler so it won't hurt performance.
I have a template method in a parent class, that should call another method from the base class. It works, if the method is explicitly defined in the base class, but it doesn't work if the method is inherited. I can't figure out what's exactly wrong with this code (although I know it's a little weird :)
class A
{
protected:
virtual void someMethod()
{
}
template <class TBaseClass>
void templateMethod()
{
TBaseClass::someMethod();
}
};
class B : public A
{
};
class C : public B
{
protected:
virtual void someMethod()
{
templateMethod<A>(); // this works
templateMethod<B>(); // this doesn't
}
};
This ends up with compiler error:
error C2352: 'A::someMethod' : illegal call of non-static member function
What exactly is wrong? I'm not looking for workarounds, that's easy. I'd like to know why is this incorrect.
In template <TBaseClass> void A::templateMethod() the invocant, this, is of type A *. So when you try to call B::someMethod on it, the compiler won't recognize it a object method call, because B is not a base class, but it can still be a static method call, so the compiler will try that, find B::someMethod inherited via A and complain it is not static. The fact that A is a base class of this is not relevant; only that B is not.
The issue is that class A is not automatically granted access to class B. The methods within the class don't know that the current instance of A is actually of type B.
To do what you're trying, you need to cast A to the target type:
template <class TBaseClass>
void templateMethod()
{
static_cast<TBaseClass*>(this)->someMethod();
}
This will work if the particular instance of A you're calling really is a B (as it is in the example you give). There is no type checking done here to be sure it is. If you pass a class that is not in the inheritance hierarchy you will be in the work of undefined behavior.
That said, your example has "someMethod()" as virtual. If you're doing what I just did here then making that method virtual may not make sense, as you are explicitly saying which instance you want. If you do leave it virtual, then just calling someMethod() directly in A will get you the most derived instance.
I think it's not working because you are trying to call a static method.
Static methods can be inherited but they can't be virtual.
Thats why A::someMethod will work and B::someMethod won"t work.
I have an abstract base class with a virtual method. In the derived class, this method is implemented. However, I want the function in the derived class as a static method in order to be able to call the function without instantiating an object of that class.
class Base
{
virtual double Foo(double rParam) const;
};
class Derived1 : public Base
{
static double Foo(double rParam);
};
class Derived2 : public Base
{
static double Foo(double rParam);
};
Essentially, Derived1 and Derived2 provide different implementations of a static function (that do not depend on object data), but I want those functions to be virtual in order to be able to call those functions in other functions of the base class. The only solution I see right now is to implement two member functions in the derived class, one being the virtual function from the base class, and the other one (with a different name) being a static function. In order to prevent doubling the source code, the virtual function could then directly call the static function (could be inlined). Any other solutions?
class Derived : public Base
{
double Foo(double rParam)const
{
return FooStatic(rParam);
}
inline static double FooStatic(double rParam);
};
I do think that the FooStatic approach you have is the best way to go about it, in terms of adhering to good OO practice. Essentially, your non-static Foo overrides work like function pointers into your static versions.
(Emphasis on "work like": you can't actually use function pointers directly, since your override for Foo has to throw away the reference to this before invoking FooStatic.)
It would not make sense to make a virtual method static. Virtual means that you choose which implementation to run based on the type of an object. In a static context you have no object.
EDIT: While the first example will compile, it will not do what you expect it to do. The static methods will not override the base implementation, but rather hide it, meaning that the static methods will never be called instead of that of the base class. The second example is fine though, I cannot see any problem with it.
Suppose I have a Base class and its derived class Derived as follows:
class Base{
private:
_privateVar;
protected:
protectedVar;
public:
publicVar;
void publicMethod(someValue, anotherValue)
{
protectedVar = someValue;
publicVar = anotherValue;
}
};
class Dervied: public Base{
protected:
protectedVar:
};
int main(void)
{
Dervied d;
d.publicMethod(valueA, valueB);
}
My question-
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
Thanks
--A
It is of Base class. Base class cannot access derived class members.
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
The method is a member of the Base class and hence it can access only the members of the Base class.
If the method belonged to your Derived class, then it would access Derived class member.
Because Derived class data members always hide Base class data members when accessed inside their own member functions.
You cannot override a member variable, you can create another different variable in a different level in the hierarchy that has the same name, but they will be two unrelated variables. Within the context of the use of the variable, lookup will find one or the other and that is the one that will be picked up and used.
Polymorphism only applies to virtual member functions, not to non-virtual functions, not to member variables either.
Since publicMethod is a methoc of the Base class, the protectedVar of the base class is set.
I don't know if this is what you want or expect, but even if this is what you want, I think it is not advised to do it like this. Tools like PC-LINT will probably also warn you about such a construction.
The member in the base class is modified. Data members never behave as if they are virtual.
When the compiler reaches the definition of Base::publicMethod, it has to statically resolve all the names it uses. At that point, the only possible resolution of those names are the members of Base, so the generated code will access those members.
Subclassing Base later on does not, and could not possibly, go back and change the code generated for Base::publicMethod. The derived class could be in a different translation unit, or in a dynamically-loaded library.
If you want dynamic lookup, access protectedVar via a protected virtual accessor function: that would allow a derived class to interpose its own storage for the variable.
If Base::protectedVar and Derived::protectedVar have the same type anyway, it's hard to see what you expect to gain, but it would look like:
class Base
{
Type protectedVarImpl;
protected:
virtual Type & protectedVar();
virtual Type const & protectedVar() const;
public:
void publicMethod(someValue, anotherValue)
{
protectedVar() = someValue; // Note the method call
publicVar = anotherValue;
}
};
Type& Base::protectedVar() { return protectedVarImpl; }