Undefined reference to class_name<template_argument>function_name(variable)? - c++

I'm getting a fatal linking error in the code below, it says:
]+0x10)||undefined reference to `base<node>::pass_derived(node)'|
I wanted to define a base class which has a pointer called poly_type and the base class can also "access" from within itself another class called derived. The problem I run into is line poly_type->pass_derived(n); where the compiler doesn't want to see the derived class where I tried to pass an object of type node. I'm guessing this is a limitation of C++, if so let me know. Heres the broken code,
edit seems like this has been asked somewhere else, I updated the source to reflect that opinion.

There is no definition of pass_derived in the base class.
You declare it as a virtual function but only define it in the derived class.
Because it instantiates base in the main function, the compiler tries to generate code for base but it does not find a definition for pass_derived.
You could add a default implementation - even if it is just empty.
As for whether you can eventually get it to call derived::pass_derived instead... :) good luck, it looks like fun. You are building your own version of inheritance?

The issue is here:
template < class T>
class base
{
// ...
virtual void pass_derived(T data);
};
You declared pass_derived as virtual but not pure virtual. Therefore, the linker raises an error if you don't provide an implementation.
Either you provide an implementation or (which I believe is your intent) you declare it pure virtual:
virtual void pass_derived(T data) = 0;
but then you cannot instantiate base<T> and must work only with pointers or references to base (which actually point/refer to derived).

Related

Overriding C++ pure virtual functions

I have the following classes:
Mode class
h-file:
#pragma once
class Mode
{
public:
virtual int recv() = 0;
};
Mode class
cpp-file:
-> empty
LocalMode class
h-file:
#pragma once
#include "Mode.h"
class LocalMode: public Mode
{
private:
public:
LocalMode();
int recv();
};
LocalMode class
cpp-file:
#include "LocalMode.h"
int LocalMode::recv(){
return 0;
}
Here are my questions:
Is the keyword "override" always necessary? If not, what are the best practices?
The main question:
I know the code above works for me. But I have the problem, that I basically have to "copy" the function signature of the pure virtual function out of the base class into my derived class. What happens, if I don't know what pure virtual functions the base class has?
My implementation above implies that I have to know all the pure virtual functions available in the base class.
I tried accessing the pure virtual function by the Mode:: scope and LocalMode:: scope but in Visual Studio I simply got some error messages (I deem those error messages to be rather irrelevant to this question).
Some plug-ins/Intellisense?
I remember that in java IntelliSense in general helped me out and added the needed functions from the abtract class. Although I am aware that java is a bit different in that sense (inheriting from abtract classes) to c++, I would also like if there are any tools which help me to include those automatically?
Skiming through the internet I could not find any examples. They all assume, that all the pure virtual functions of the base class are known ...
I am just imaging that if I had a abstract class with a lot of pure virtual functions and I forgot to copy just one of them, when instantiating I would get an error ...
Thank you in advance.
Is the keyword "override" always necessary? If not, what are the best practices?
It is never "necessary". Overriding works with or without this keyword. It is only here to help you prevent issues like typos etc.
struct A
{
virtual int foo();
};
struct B: public A
{
int fooo(); //whoops, not overriding, no compiler error
};
struct C: public A
{
int fooo() override; //compiler error, compiler noticed my typo
};
So, the best practice is to always use override keyword when you want to override a virtual function.
The main question: I know the code above works for me. But I have the problem, that I basically have to "copy" the function signature of the pure virtual function out of the base class into my derived class. What happens, if I don't know what pure virtual functions the base class has?
You cannot not know that. To derive from class, compiler requires full definition of that class, which typically means you have #included it (and you have access to that definition).
My implementation above implies that I have to know all the pure virtual functions available in the base class. I tried accessing the pure virtual function by the Mode:: scope and LocalMode:: scope but in Visual Studio I simply got some error messages (I deem those error messages to be rather irrelevant to this question).
Are you looking for reflection mechanism? It's not present in C++, so you cannot e.g. get a list of function for given class. If you want to call pure virtual function from another function, that cannot work because, well, they are pure virtual.
Some plug-ins/Intellisense?
That is explicitly off-topic for StackOverflow, but there are many IDEs for C++, you shouldn't have any trouble finding them.

Question about Pure Virtual Functions in C++?

I am reading some C++ text regrading Pure Virtual Functions. As the text says, the form of Pure Virtual Functions declaration, for example, is:
virtual void virtualfunctioname() = 0;
And the text explains: "Since pure virtual function has no body, the programmer must add the notation =0 for declaration of the pure virtual function in the base class."
I have tried to remove = 0;, that means I only declared virtual void virtualfunctioname(); and things worked fine.
So, why do we need to assign a 0 to the virtual function?
Thanks
If a class has any pure virtual functions, it cannot be instantiated. Also, it forces any derived classes to implement those functions, otherwise they too cannot be instantiated.
So if you remove the = 0, you'll just have a normal base class, which may be instantiated, and doesn't enforce an interface on its derived classes. You'll only get into trouble if you instantiate a base-class object (or a derived-class object with no override), and then try to invoke virtualfunctionname() on it, because there's no definition for it, so the linker will complain.
[Note, also the claim that "pure virtual functions have no body" is incorrect; you may define an implementation for a pure virtual. The class will still be abstract, though.]
If you don't declare a method as pure virtual, the compiler will assume there is an implementation of it somewhere. If you never instantiate the class that is supposed to contain those pure virtual (and abstract class to use the right terminology), you will be fine. However, if you do, the compiler will accept the code as valid and you will get a linker error later.
If you mark a method as pure virtual, the class containing it will be marked as abstract and the compiler will refuse any attempts to instantiate it.
things worked fine
I assume you meant that the code compiled and linked. However, you probably haven't defined an implementation for virtualfunctionname in the base class you declare it, so if you ever do call the base implementation you will get a linker error.
At the moment things probably work because you provide an implementation in a derived class and use that instead.
When you declare a function as pure virtual function that class which contain it will known as abstract class and no instance would be created.
Again no instance of that class would be created.This class is used for inheritance and the derived class must implement this method. otherwise compilation error will appear.
Thanks

Why can't we create objects for an abstract class in C++?

I know it is not allowed in C++, but why? What if it was allowed, what would the problems be?
Judging by your other question, it seems you don't understand how classes operate. Classes are a collection of functions which operate on data.
Functions themselves contain no memory in a class. The following class:
struct dumb_class
{
void foo(){}
void bar(){}
void baz(){}
// .. for all eternity
int i;
};
Has a size of int. No matter how many functions you have ever, this class will only take up the space it takes to operate on an int. When you call a function in this class, the compiler will pass you a pointer to the place where the data in the class is stored; this is the this pointer.
So, the function lie in memory somewhere, loaded once at the beginning of your program, and wait to be called with data to operate on.
Virtual functions are different. The C++ standard does not mandate how the behavior of the virtual functions should go about, only what that behavior should be. Typically, implementations use what's called a virtual table, or vtable for short. A vtable is a table of function pointers, which like normal functions, only get allocated once.
Take this class, and assume our implementor uses vtables:
struct base { virtual void foo(void); };
struct derived { virtual void foo(void); };
The compiler will need to make two vtables, one for base and one for derived. They will look something like this:
typedef /* some generic function pointer type */ func_ptr;
func_ptr __baseTable[] = {&base::foo};
func_ptr __derivedTable[] = {&derived::foo};
How does it use this table? When you create an instance of a class above, the compiler slips in a hidden pointer, which will point to the correct vtable. So when you say:
derived d;
base* b = &d;
b->foo();
Upon executing the last line, it goes to the correct table (__derivedTable in this case), goes to the correct index (0 in this case), and calls that function. As you can see, that will end up calling derived::foo, which is exactly what should happen.
Note, for later, this is the same as doing derived::foo(b), passing b as the this pointer.
So, when virtual methods are present, the class of the size will increase by one pointer (the pointer to the vtable.) Multiple inheritance changes this a bit, but it's mostly the same. You can get more details at C++-FAQ.
Now, to your question. I have:
struct base { virtual void foo(void) = 0; }; // notice the = 0
struct derived { virtual void foo(void); };
and base::foo has no implementation. This makes base::foo a pure abstract function. So, if I were to call it, like above:
derived d;
base* b = &d;
base::foo(b);
What behavior should we expect? Being a pure virtual method, base::foo doesn't even exist. The above code is undefined behavior, and could do anything from nothing to crashing, with anything in between. (Or worse.)
Think about what a pure abstract function represents. Remember, functions take no data, they only describe how to manipulate data. A pure abstract function says: "I want to call this method and have my data be manipulated. How you do this is up to you."
So when you say, "Well, let's call an abstract method", you're replying to the above with: "Up to me? No, you do it." to which it will reply "##^##^". It simply doesn't make sense to tell someone who's saying "do this", "no."
To answer your question directly:
"why we cannot create an object for an abstract class?"
Hopefully you see now, abstract classes only define the functionality the concrete class should be able to do. The abstract class itself is only a blue-print; you don't live in blue-prints, you live in houses that implement the blue-prints.
The problem is simply this:
what should the program do when an abstract method is called?
and even worse: what should be returned for a non-void function?
The application whould proabably have to crash or thow a runtime exception and thus this would cause trouble. You can't dummy-implement every abstract function.
A class can simply be declared abstract where it has no abstract methods. I guess that could be instantiated in theory but the class designer doesn't want you to. It may have unintended consequences.
Usually however abstract classes have abstract methods. They can't be instantiated for the simple reason that they're missing those methods.
Because logically it does not make any sense.
An abstract class is a description that is incomplete.
It indicates what things need to be filled out to make it complete but without those bits its not complete.
My first example was a chess game:
The game has lots of pieces of different type (King,Queen,Pawn ... etc).
But there are no actual objects of type piece, but all objects are instances of objects derived from piece. How can you have an object of something that is not fully defined. There is not point in creating an object of piece as the game does not know how it moves (that is the abstract part). It knows it can move but not how it does it.
Abstract classes are non-instantiable by definition. They require that there be derived, concrete classes. What else would an abstract class be if it didn't have pure virtual (unimplemented) functions?
It's the same class of question as why can't I change the value of a const variable, why can't I access private class members from other classes or why can't I override final methods.
Because that's the purpose of these keywords, to prevent you from doing so. Because the author of the code deemed doing so dangerous, undesired or simply impossible due to some abstract reasons like lack of essential functions that need to be added by specific child classes. It isn't really that you can't instantiate because a class is virtual. It's that inability to instantiate a class defines it as virtual (and if a class that can't be instantiated isn't virtual, it's an error. Same goes the other way, if instance of given class makes sense, it shouldn't be marked as virtual)
Why we cant create an object of an abstract class?
simply abstract class contains abstract methods(means the functions which are without the body) and we cannot give functionality to the abstract methods. And if we try to give functionality to the abstract methods then there will be no difference between abstract class and virtual class. So lastly if we create an object Of an abstrast class then there is no fun to call the useless functions or abstract methods as they are without the functionality..so thats why any language doesnt allow us to create an object of an abstract class..
Abstract classes instantiated would be pretty useless, because you would be seeing a lot more of "pure virtual function called". :)
It's like: we all know that a car would have 3 pedals and a steering wheel and a gear stick. Now, if that would be it, and there'd be an instance of 3 pedals and gear stick and a wheel, I'm not buying it, I want a car, like with seats, doors, AC etc. with pedals actually doing something apart from being in existence and that's what abstract class doesn't promise me, the ones implementing it do.
Basically creation of object is responsible for allocation of memory for member variables and member functions. but here, in pure virtual function we have declaration and defination in derived class.so creation of object generates error.

dynamic_cast fails

I have a base class and a derived class. Each class has an .h file and a .cpp file.
I am doing dynamic_cast of the base class object to the derived class in the following code:
h files:
class Base
{
public:
Base();
virtual ~Base();
};
class Derived : public Base
{
public:
Derived(){};
void foo();
};
class Another
{
public:
Another(){};
void bar(Base* pointerToBaseObject);
};
cpp files:
Base::Base()
{
//do something....
}
Base::~Base()
{
//do something....
}
void Derived::foo()
{
Another a;
a.bar(this);
}
void Another::bar(Base* pointerToBaseObject)
{
dynamic_cast<Derived*>(pointerToBaseObject)
}
From some strange reason, the casting fails (returns NULL). However, the casting succeeds if I move the implementation of Derived class's constructor from .h to the .cpp file.
What can cause it?
The compiler is gcc 3.1, on Linux-SUSE. BTW, I see this behavior only on this platform, and the same code works fine in Visual Studio.
Do you have any virtual function in Base? It won't work otherwise. If nothing else, make its dtor virtual.
Don't know whether it was already asked by the other guy that deleted his answer, but i believe it was something different: Are you doing the dynamic_cast from the bases' constructor? If so, that won't work. The compiler will think that the Base is the most derived type, similar to when you call a virtual function and it ends up calling the version of the Base.
The code, as posted, shouldn't fail, provided you have a virtual function in the base class (as litb pointed out).
But I believe every current compiler generates a "Base class is not polymorphic" kind of error if you hadn't, so that probably won't be the problem.
The only thing I can think of is that due to some weird bug everything gets inlined and no vtable gets generated. But if you put the constructor in the C++ file, the compiler decides not to inline everything, triggering the creation of a vtable, causing your cast to work.
But this is very wild guesswork, and I don't think any compiler would have such a mistake in it (?)
If you want a definite answer, post more code. And the compiler / platform used.
EDIT: Seeing the updated code
I think you should at least derive Derived from Base ;) (I suppose that's a typo)
But after seeing the code, the only thing I can think of is that gcc (wrongly) inlines everything and doesn't generate a vtable for Derived. For what it's worth, this runs fine compiled with gcc 4.0
3.1 is over 7 years old by now... if there's any possibility to upgrade I'd go for it.
Make the destructor virtual, and place it (or at least one virtual method) in the .cpp file.
Some compilers (read: gcc) look for the first-encountered non-inline virtual method body and use it to decide where to put the virtual method table. If you don't have any virtual methods with bodies in a .cpp file, the virtual method table is not created.
You must have at least one virtual method for dynamic_cast to work. Dynamic cast uses the table to figure out type information, and no table is created if there are no virtual methods.
If you have a class that you expect to be subclassed and it has a destructor or if the class has any instance variables that are classes with destructors, then you'll really want to make your destructor virtual (even if it has an empty body). Otherwise the cleanup you expect won't happen for subclass instances.
Are you doing this in Visual C++? I think you use to have to enable runtime type information (RTTI) in the compiler setting for this to work.
Please don't flame me if I've got this wrong. It's been a while since I used C++!!!
In looking at your code, I don't see any inheritance. Did you forget to do that? Derived isn't derived from anything.
In the code you have posted Derived is not derived from Base.
Edit: FYI, modified code works fine with g++ 3.4.5

Is there a way to prevent a method from being overridden in subclasses?

Is anyone aware of a language feature or technique in C++ to prevent a child class from over riding a particular method in the parent class?
class Base {
public:
bool someGuaranteedResult() { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
Even though it's not virtual, this is still allowed (at least in the Metrowerks compiler I'm using), all you get is a compile time warning about hiding non-virtual inherited function X.
When you can use the final specifier for virtual methods (introduced with C++11), you can do it. Let me quote my favorite doc site:
When used in a virtual function declaration, final specifies that the function may not be overridden by derived classes.
Adapted to your example that'd be like:
class Base {
public:
virtual bool someGuaranteedResult() final { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
When compiled:
$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’
When you are working with a Microsoft compiler, also have a look at the sealed keyword.
A couple of ideas:
Make your function private.
Do not make your function virtual. This doesn't actually prevent the function from being shadowed by another definition though.
Other than that, I'm not aware of a language feature that will lock away your function in such a way which prevents it from being overloaded and still able to be invoked through a pointer/reference to the child class.
Good luck!
Sounds like what you're looking for is the equivalent of the Java language final keyword that prevents a method from being overridden by a subclass.
As others here have suggested, you really can't prevent this. Also, it seems that this is a rather frequently asked question.
(a) I dont think making function private is the solution because that will just hide the base class function from the derived class.The derived class can always define a new function with the same signature.
(b) Making the function non virtual is also not a complete solution because, if the derived class redefines the same function , one can always call the derived class function by compile time binding i.e obj.someFunction() where obj is an instance of the derived class.
I dont think there is a way of doing this.Also,i would like to know the reason for your decision to prohibit derived classes from overriding base class functions.
a compile time warning about hiding non-virtual inherited function X.
change your compiler settings to make it a error instead of warning.
I guess what the compiler warns you about is hiding !! Is it actually being overridden ?
compiler might give you a warning, but at runtime, the parent class method will be called if the pointer is of type parent class, regardless of the actual type of the object it points to.
This is interesting. Try making a small standalone test program for your compiler.
For clarification, most of you misunderstood his question. He is not asking about "overriding" a method, he is asking whether there is a way to prevent "hiding" or not. And the simple answer is that "there is none!".
Here's his example once again
Parent class defines a function:
int foo() { return 1; }
Child class, inheriting the Parent defines the same function AGAIN (not overriding):
int foo() { return 2; }
You can do this on all programming languages. There is nothing to prevent this code from compiling (except a setting on the compiler). The best you'll get is a warning that you are hiding the parent's method. If you call the child class and invoke the foo method, you'll get 2. You have practically broken the code.
This is what he is asking.
If you address the child class as a type of its parent, then a non-virtual function will call the parent class's version.
ie:
Parent* obj = new Child();
Unless you make the method virtual, the child class cannot override it. If you want to keep child classes from calling it, make it private.
So by default C++ does what you want.
Trying to prevent someone from using the same name as your function in a subclass isn't much different than trying to prevent someone from using the same global function name as you have declared in a linked library.
You can only hope that users that mean to use your code, and not others', will be careful with how they reference your code and that they use the right pointer type or use a fully qualified scope.
In your example, no function is overridden. It is instead hidden (it is a kind of degenerated case of overloading).
The error is in the Child class code. As csmba suggested, all you can do is changing your compiler settings (if possible) ; it should be fine as long as you don't use a third party library that hides its own functions.
Technically u can prevent virtual functions to be be overridden. But you will never ever been able to change or add more. That is not help full. Better to use comment in front of function as faq lite suggests.
I was searching for same and yesterday came to this [rather old] question.
Today I found a neat c++11 keyword : final . I thought it may be useful for next readers.
http://en.cppreference.com/w/cpp/language/final
C++ methods are private and un-overridable by default.
You cannot override a private method
You cannot override a non-virtual method
Are you perhaps referring to overloading?