Woverloaded-virtual warning on usual method - c++

I'm confused why the following code produces Woverloaded-virtual warning.
class TestVirtual
{
public:
TestVirtual();
virtual void TestMethod(int i);
};
class DerivedTestVirtual : public TestVirtual
{
public:
void TestMethod();
};
Derived class has usual method TestMethod with no parameters - signature differs from similar virtual method of base class. Then why compiler cannot resolve this situation?

The reason for the warning is that the no parameter version is hiding the int version from the base class.
DerivedTestVirtual tdv;
tdv.TestMethod(0); // This line will cause an error.
You can circumvent that by declaring you use all of the original overloads from the base, like so:
class DerivedTestVirtual : public TestVirtual
{
public:
using TestVirtual::TestMethod;
void TestMethod();
};
The warning is there to bring the issue to your attention. And it's also useful since such a mistake can happen when you try to override it, but accidentally end up overloading. Though nowadays you'd use the override specifier to catch that instead.

Related

How do I fix the unimplemented pure virtual method error? [duplicate]

Here is the problem: I keep getting the unimplemented pure virtual method error when trying to compile. I have implemented all of the pure virtual methods in the abstract base class. Any ideas?
here is the abstract base class:
class record{
public:
virtual int getID()=0;
virtual record *clone();
};
and the implementation:
class sdata: public record{
public:
sdata(std::string s = ""){data=s; ID=atoi(data.substr(0,8).c_str());}
virtual int getID(){return ID;}
private:
std::string data;
int ID;
};
sorry, here is the complete error message:
Unimplemented pure virtual method 'getID' in 'record'
Perhaps this bit of code is causing the error then:
int hashTable::hash(record *x) {
return floor(m * (x->getID() * A - floor(x->getID() * A)));
}
Without seeing the code causing the error, it's difficult to know exactly what's going on. If this is a compile-time error, I don't see anything here that would cause it.
However, if you're seeing a runtime error, the two most common causes of this that I can think of are:
(1) Calling the member function from within the base class's constructor or destructor (even indirectly).
(2) The derived class calling the base class's version of the function without it being implemented.
An example showing both of these errors would be:
struct Base {
Base()
{
call_foo(); // Oops, indirectly calls Base::foo() (Scenario 1)
}
void call_foo() const {
foo();
}
protected:
virtual void foo() const = 0;
};
struct Derived : Base {
protected:
virtual void foo() const {
Base::foo(); // Oops, unimplemented virtual base function (Scenario 2)
}
};
int main() {
Derived().call_foo();
}
== UPDATE: Possible compile-time error ==
I observe in your example code that record has a non-pure-virtual clone() member function returning a record *. Since record is abstract, you can't create a record directly (only its concrete subclasses). This suggests that your clone() member function should probably also be pure virtual; if it tries to (for example) return new record(), you will get an error that your base class has pure virtual functions.
It sounds like you have not implemented all the functions from the abstract base class. If a function in your base has the signature:
void SomeFuction() const;
And you implement the following in your derived class:
void SomeFuction();
Then you have have not implemented the function because you omitted the const. GCC should tell you what you did not implement.
Related: if you had a concrete implementation of the base, you would have hidden its name in the derived class. To find functions you are [accidentally] hiding, use -Woverloaded-virtual.

How protect extended class when someone change a virtual method

A very basic question. If you have a base class with virtual method and an extended class with the overloading of that virtual method. For example:
class Base
{
protected:
virtual void method(int a_1,int a_2);
};
class Extended:public Base
{
protected:
void method(int a_1,int a_2)
};
What is a good practice to avoid someone change Base method definition without change the method in the
exteded class? Is there any solution for detect this in compilation time ? BTW I am using VS2005, then I can't use C++11 or above.
If your compiler supports C++11 you can use override.
In your case, if you add override to the method in Extended class, compiler will rise an error if someone changes the method definition in Base class without changing it in Extended.
class Extended:public Base
{
protected:
void method(int a_1,int a_2) override;
};

Disabling visual C++ virtual function override warning for certain methods

I would like to enable C4263 (Visual C++) warning on our code base, however, the warning gives out some false positives. We would like to disable the warning such that only the false positives disappear. I tried to simplify the issue with some generic code:
class B {
public:
virtual void funcA();
virtual void funcB();
};
class D : public B
{
virtual void funcA(int);
virtual void funcB(int);
};
With this code we I get following warnings:
void D::funcA(int)' : member function does not override any base class virtual member function
void D::funcB(int)' : member function does not override any base class virtual member function
What I am trying to achieve is to disable the warning for funcA (or funcB) and let the rest of the class be affected by it.
I tried putting
#pragma warning(push)
#pragma warning(disable:4263)
.
.
.
#pragma warning(pop)
around funcA but that does not solve the problem. If the pragmas wrap the whole class that both of the warnings disappear.
Any ideas?
This is a strange error given the documentation for it:
https://msdn.microsoft.com/en-us/library/ay4h0tc9.aspx?f=255&MSPPError=-2147217396
'function' : member function does not override any base class virtual
member function
A class function definition has the same name as a virtual function in
a base class but not the same number or type of arguments. This
effectively hides the virtual function in the base class.
The last sentence is the interesting one, and it suggested to me that if you unhide the base class functions, the warning will no longer appear.
And indeed this is the case. The following code does not output C4263:
class B {
public:
virtual void funcA();
virtual void funcB();
};
class D : public B
{
using B::funcA;
using B::funcB;
virtual void funcA(int);
virtual void funcB(int);
};
The warning seems a little strange. If you're dispatching from the base class pointer, it doesn't matter what functions the derived class hides, as they won't be hidden when using a base class pointer. But herein lies the answer!
What's actually happening here is the compiler is guessing your intentions. Because you are introducing a new signature, it means you will be using either polymorphic or non-polymorphic dispatch using a derived pointer (not a base pointer). If you were not doing this, it would be impossible to call your overload. The compiler figures that if you are doing this, you will be hiding the un-overridden functions. And that's what the warning is about.
In an example:
struct Base
{
virtual void DoThing(int)
{
std::cout << "INT " << std::endl;
}
};
struct Derived: public Base
{
virtual void DoThing(char) // Add a function to handle chars
{
std::cout << "CHAR " << std::endl;
}
};
int main()
{
Derived *derived = new Derived;
Base *base = derived;
base->DoThing(1);
derived->DoThing(1);
derived->DoThing('a');
}
This outputs:
INT CHAR CHAR
The intention may have been to add an overload to handle a different case, but instead it's hiding all the existing overloads. The warning is correct given the rules of the language. The warning isn't exact, it's trivial to determine cases where it doesn't get invoked but it should. It in-fact does the opposite of false-warnings :)
To defeat this warning, the using declaration should be used.

C++ Implement subclasses that extends subInterfaces without overriding already overriden methods

I created Interfaces (abstract classes) that expends other Interfaces in C++ and I tried to implement them but errors occur when I compile.
Here are the errors:
main.cpp: In function 'int main()':
main.cpp:36:38: error: cannot allocate an object of abstract type 'Subclass'
Subclass * subObj = new Subclass();
^
Subclass.h:13:7: note: because the following virtual functions are pure within 'Subclass':
class Subclass : SubInterface {
^
SuperInterface.h:13:18: note: virtual void SuperInterface::doSomething()
virtual void doSomething()=0;
Here are my sources:
#include <iostream>
class SuperInterface {
public:
virtual void doSomething() = 0;
protected:
int someValue;
};
class SubInterface : public SuperInterface {
public:
virtual void doSomethingElseThatHasNothingToDoWithTheOtherMethod() = 0;
protected:
int anotherValue;
};
class Superclass : public SuperInterface {
public:
Superclass() {}
virtual ~Superclass() {}
void doSomething() {std::cout << "hello stackoverflow!";}
};
class Subclass : public SubInterface {
public:
Subclass() {}
virtual ~Subclass() {}
void doSomethingElseThatHasNothingToDoWithTheOtherMethod() {std::cout << "goodbye stackoverflow!";}
};
int main(void)
{
Superclass * superObj = new Superclass();
Subclass * subObj = new Subclass();
}
Here's what I want:
I want my implementation to be aware and so have the same behaviour as of already overriden methods (e.g subObj->doSomething() method works without the need to implement it again). Can anyone tell me what I should do to make that happen if it's even possible? Thanks.
No, you can't do what you want through simple inheritance. At no point does Subclass inherit, or provide, an implementation of doSomething(), so you can't call subObj->doSomething() as you desire. You must honour the interface contract of subInterface.
You could inherit Subclass from Superclass and Subinterface, and just implement doSomething() as a kind of proxy, Superclass::doSomething(). You still need an implementation but you don't have to 're-implement' it.
You're getting the error because you're trying to create an object of an abstract class.
Your Subclass is an abstract class because of this line void doSomethingElse()=0;.
If a class has one pure virtual function, it will be an abstract class. You can't create an object of an abstract class, you can only have a reference or a pointer to it.
To get rid of the error, the declaration of doSomethingElse in Subclass should be
void doSomethingElse();
Instead of void doSomethingElse()=0;
Also I don't see why you need two interfaces. You could derive Subclass from the SuperInterface, as it is basically just the same as SubInterface
To be honest, I am not entirely sure what your design wants to express, but there are at least two technical errors here:
1.) You use private inheritance in all cases, so you do not actually deal with "interfaces" at all. Public inheritance is achieved like this:
class SubInterface : public SuperInterface
2.) You use =0 for a function you apparently want to implement.
This will fix the compiler errors, but the design is still questionable. Considering the motivation you gave at the end of your question, I recommend composition rather than (public) inheritance. In C++, to share functionality is best expressed with composition. To put it very brief, encapsulate the commonly used functionality in a separate class and equip the other classes with an object of it.
class CommonFunctionality
{
//...
public:
void doSomething();
void doSomethingElse();
};
class SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
class SubClass : public SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
In fact, perhaps you don't even need to create a class for CommonFunctionality. Perhaps simple free-standing functions would do. Programmers with a Java background (and your code looks a bit like it) tend to put too stuff into classes than what is necessary in C++.
Your class 'Subclass' should override 2 pure virtual methods, so:
class Subclass : SubInterface {
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() override;
void doSomething() override;
};
by not doing so or stating
void doSomethingElse()=0;
class Subclass becomes abstract too, which cannot be instantiated. You could havea look at :http://www.parashift.com/c++-faq-lite/pure-virtual-fns.html
Here's what I want: I want my implementation to be aware and so have
the same behaviour as of already overriden methods (e.g
subObj->doSomething() method works without the need to implement it
again). Can anyone tell me what I should do to make that happen if
it's even possible!!?? Thanks.
--> maybe declare the methods virtual not pure virtual
There are 2 problems, which are clearly stated by compiler:
Problem 1
SubInterface::doSomethingElse()() in Subclass is declared as pure virtual, disregarding that you trying to define it in source file (I'm pretty sure, that this is a copy-paste kind of errors).
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() = 0; // still pure?
};
Solution is obvious:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomethingElse() override
{
}
};
(here using C++11 override specifier, so compiler will check correctness of overriding; it is not obligatory)
Problem 2
doSomething() is not even tried to be overriden, neither in SuperInterface, nor in Subclass, so it stays pure virtual. Although doSomething() is overriden in Superclass, Subclass has no idea about existance of Superclass.
Solution: override doSomething() either in SuperInterface, or in Subclass, or in any of children of Subclass (don't have them yet). For example, overriding in Subclass:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomething() override
{
}
virtual void doSomethingElse() override
{
}
};
Other issues:
You are inheriting without visibility specifier, i.e. privately. Use public inheritance until you really need something else:
class Derved : public Base {};
Your source files have .c extension, but containing C++ code. This can confuse some compilers if you do not state programming language explicitly via command line arguments. By convention, most programmers use .cpp extension, and most compilers treat such files as C++ source files.

Is it possible to prevent a member function from being redefined?

I would like a class B not to be able to redefine one of the member function of its base class A. Is there a way to do that?
EDIT:
Thanks for the answers. Can I prevent non-virtual member functions from being overridden as well?
If you mean disallowing a derived class to override a virtual function of its base class, C++11 introduced a way to do that with a final virt-specifier (as it's called in the standard):
struct B{
virtual void f() final;
};
struct D : B{
void f(); // error: 'B::f' marked 'final'
};
I don't know which compilers support that, though. Probably GCC 4.7 and Clang.
If your methods are virtual, in C++11 you can prevent overriding them with final.
class A
{
public:
virtual void foo() final;
};
class B : public A
{
public:
void foo(); // <-- error
};
You can't prevent hiding.
Can I prevent non-virtual member functions from being overridden as
well?
No you can't, BUT from another side you can... if you're not shore if will you acctualy override base method or not in your derived class you can check whther you're overriding an method or not using a keywod override
when applying that keywod to your method you make shore that you accutaly realy want override that mathod.
so if signature of inherted method is the same as the signature of base method you'll get compile time error, say that derived method does not override base method.
so using override keyword you are telling the compiler that you DO NOT want to everride it.
by not using override keywod you never know wether you override it or not.
consider following example:
class A
{
public:
void f() {std::cout << "A";}
};
class B : public A
{
public:
void f() override {std::cout << "B";}
};
this result in compile time error because you can't override base method.
by not using the override keyword you'll of course be able to override it.
override keywod is introduced in C++0x standard and is supported by visual studio 2010.