Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have boiled down my issue to the following code all in a single *.cpp file:
class A {
public:
A() {};
int PerformAction() {
return Action();
}
protected:
virtual int Action();
}
class B: public A {
protected:
int Action();
}
int B::Action() {
return 4;
}
int main() {
B newB;
newB.PerformAction();
};
The previous code throws an Unresolved external symbol error on B::Action(). Changing a::Action()'s definition to:
virtual int Action() = 0;
yields instead the Cannot instantiate abstract class compiler error where it is used in the main function. All of the answers I have seen relate to having the code spread across multiple files, but this is occurring all within one source file. I imagine it is related to B's implementation of Action() being outside the class definition of B but can't see any reason why it should cause any error.
Your error messages, taken together, indicate a signature mismatch between A::Action and B::Action, such that B::Action does not become an overrider. The signatures must match perfectly (including cv-qualification of this), except that return type covariance is allowed.
And B::Action must be virtual. It will be implicitly if the signature matches, unless it is a template. Templates can't override.
If you have a C++11 compiler, I suggest using the override keyword, to make signature mismatch a compile error.
The previous code throws an Unresolved external symbol error on B::Action().
Indeed, all non-pure virtual functions must be defined, so that their address can be stored in the virtual function table for the class.
yields instead the Cannot instantiate abstract class compiler error
No it doesn't: http://ideone.com/IS7PJj
You'd get that error if you tried to directly instantiate A, or a subclass which didn't override the pure virtual function. B does override it, and so is not abstract.
Possibly, your real class B has an incorrect signature for Action, so it doesn't actually override the one declared in A. In C++11, you can add the override specifier to the one in B, to get a more helpful error message in that case.
I imagine it is related to B's implementation of Action() being outside the class definition of B
No, that shouldn't be an issue, as long as there's exactly one definition of the function.
Related
This question already has answers here:
Can virtual functions be constexpr?
(3 answers)
Closed 1 year ago.
I'm implementing a pure virtual function in a C++ derived class, and mark the method final. I would also like to mark the function constexpr, but it appears the standard doesn't allow this.
Is there any practical reason why it would be difficult for compilers to implement this? Or is such a feature omitted due to the usual "this feature wasn't deemed to be important enough to add to the standard" thinking?
Based on the comments, it seems my original question didn't make it clear I am asking about constexpr final functions. The following code illustrates what I am trying to compile:
struct A {
virtual int foo() const;
};
struct B : public A {
// Note that this function is final, and is therefore no longer
// polymorphic in types derived from B (e.g., the function call
// no longer requires a lookup in the virtual method table
// when the compile-time type is known to be derived from B)
constexpr int foo() const final {
return 0;
}
};
Note that this was flagged as a duplicate of Can virtual functions be constexpr?, since in C++20, the above code would compile with or without the final keyword.
C++20 adds support for this code.
On godbolt, we can try it out: https://godbolt.org/z/f64e93dzY
It looks like this is Defect Report 647
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm fairly confident in C and Java and just started using C++, still getting used to the basics about best practices including data abstraction (which, as far as I understand, means proper header usage).
I'd like to make a project that solves different types of problems that all imply reading data from a file, solving the problem and writing the result to a new file, so I figured I'd use something similar to an interface in Java.
My header looks like this:
#include <iostream>
using namespace std;
class Problem {
public:
/*
* Read data from file.
*/
virtual bool read(string filename) = 0;
/*
* Solve problem.
*/
virtual void solve() = 0;
/*
* Write solution to file.
*/
virtual bool write(string filename) = 0;
};
class Brothers : public Problem {};
I'm trying to implement the first function in my Brothers.cpp source file like this:
bool Brothers::read(string filename) override {...}
Which, save for the Brothers:: part, is how I would normally implement this function if I had just source files.
I'm getting the errors Function 'read' was not declared in class 'Brothers' and Function doesn't override any base member functions, and I would like to understand why this approach isn't working and what I should do instead.
Even though you are overriding the base class declaration, unlike in java, you will still need to declare the function in the derived class's header file. The compiler only looks in the class associated with that function, so when you say that there is a function read in Brother and it can't see that there is one explicitly, you get an error.
Another thing is that when you use interfaces or other abstract classes, everything that is declared as pure virtual has to be defined before there is a class that is not pure virtual, so in this example:
class A
{
virtual void foo() = 0;
}
class B : public A
{
virtual int bar()
{
return 0;
}
}
class C : public B
{
virtual void foo()
{
// Do something
}
}
Class A is abstract because it has a pure virtual function, but so is B because it still has no definition for foo(). Until there is a definition for it, there can be no non-abstract classes.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
In C++, i am not able to understand, when a base class pointer stores the address of derived class object it is not able to call the derived class member function?
#include <iostream>
using namespace std;
class Base
{
public:
virtual void show()
{
cout<<" In Base ";
}
};
class Derived: public Base
{
public:
int x;
void show()
{
cout<<"In Derived ";
}
Derived()
{
x = 10;
}
};
int main(void)
{
Base *bp, b;
Derived d;
bp = &d;
bp->show();
cout << bp->x;
return 0;
}
According to me:
derived d => allocates the memory to this object(therefore to x also ) say at address 200,
bp = &d; => it allocated the address 200 to bp. Now it should be able to call bp->x?
But it gives a error.
bp->x gives an error because bp is a pointer to an object of type Base, and Base doesn't have a variable called x, only Derived does.
If x was moved up into Base it would be accessible from both Base and Derived if it's public or protected.
Binding of names happens in run time. so at compilation bp is of type base. so compiler doesn't know anything about derived type assignment. so its saying there is no variable called x in base.
That's where concept of virtual functions come into picture. but hey are only for functions not variables.
In C++, i am not able to understand, when a base class pointer stores
the address of derived class object it is not able to call the derived
class member variable?
Well yes you can, you just need to cast the pointer to the class where the member variable is present
cout << dynamic_cast<Derived*>(bp)->x;
Why is bp->x is a error?
Because at compile time, the compiler can't tell what it points to. What if it was actually, a pointer to the base class? Then, x would be completely absent from the underlying object...
To answer the title question: when you have a pointer to base class that actually points to a derived class instance, then a call to a public functions declared virtual in the based class and reimplemented in the derived class will end up being a call to the derived class' implementation of that function (there are subtelties involved, with private/public access and name hiding that may interfere, but this is roughly how it works).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Under the hood, a C++ method of a class is like a C function whose first parameter is an instance of the class - or struct.
For example:
void Foo::Do();
would be equivalent to this declaration in C:
void Do(Foo* this);
Hence, using a member m_someMember from within a method is like using this->m_someMember from inside the C function.
After so many years of C/C++ programming experience, I just recently asked myself: What if I call a method from an instance pointer that is NULL???
My guess was: If the method refers to no member at all, when why would it crash?
So I did a quick test (on a Windows platform, with Visual C++ 2008):
class Foo
{
public:
Foo() {}
virtual ~Foo() {}
void Do();
};
void Foo::Do()
{
cout << "Calling 'Do' for " << this << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo foo;
foo.Do();
Foo* pNullFoo = 0;
pNullFoo->Do();
return 0;
}
Which gives an output like:
Calling 'Do' for 0038FE5C
Calling 'Do' for 00000000
This could be an hassle when doing post-mortem debugging of a crash over an instance pointer that is null. You might think that this method cannot be called if this is invalid.
On the other hand, if the method is declared virtual:
virtual void Foo::Do() { ... }
Then the line:
pNullFoo->Do();
will produce an page fault exception. Why? Because instances of a class with virtual methods have a pointer to the vtable to the child class virtual methods they belong to.
So the first thing the compiler would do is to make pNullFoo to access its vtable member, then bang!
In conclusion, this is better design to have non contextual functions like Do be implemented as procedural routines than methods, unless they are virtual.
Calling a member function on a NULL pointer invokes undefined behavior. Undefined doesn't mean it's going to crash, nor does it mean it's going to do the right thing - it's undefined. Anything could happen.
The only time I've seen this in production code is with Microsoft's CWnd::GetSafeHWND function. But since they wrote the compiler, they can get away with it.
The proper design for member functions that don't need to access any member data is to have them defined as static:
static void Do();
Then call it like:
Foo::Do();
And you don't even need to have an object or a pointer to do that.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I know the virtual keyword does not need to be resused in a derived class member function declaration if it overrides a virtual base function but is it good practice to do so to make it clear that it is virtual? Also, what about the presence of the const keyword in declaration and/or definition? I think Alexandrescu mentions something about this but I can't recall what it was?
Your question seems very confused. virtual is optional when overriding a base-class method. const is never optional if you need it. This does not do what you think it does:
struct A
{
virtual void Func() const;
};
struct B : public A
{
virtual void Func();
};
The struct B has two functions named Func. One of them will be called when the object it is called on is const, and the other will be called when it is not const. Nothing in this code has been overridden; these are two separate virtual functions.
You cannot just ignore the const and expect everything to work out fine.
Indeed, this example also shows why you should use virtual when you're overriding in derived classes. In this case, it's fairly obvious that you intended to override a base class function, but you got the function signature wrong. Without the virtual there, there would not be an immediate indication that you intended to override something.
It's not a huge help, but it's something.
C++11 provides a better solution (in that it actually solves the problem) with the override pseudo-keyword.
struct A
{
virtual void Func() const;
};
struct B : public A
{
virtual void Func() override; //Gives a compiler error, since it is not overriding a base class function.
};