Template inheritance in C++ and undefined symbols on Xcode - templates

I have seen many related questions to this problem, but after carefully following advice from members, my problem still persists. The code is quite simple. I only have the following header file ("instrument.h"), which contains the base class and the template class:
#include <stdio.h>
#include <string>
using namespace std;
class Instrument
{
public:
Instrument();
virtual void print() const = 0;
};
template <class parameter> class Equity : public Instrument
{
public:
Equity();
virtual void print() const;
};
Now, in my main function on main.cpp I only do the following:
#include "instrument.h"
#include <iostream>
int main() {
Equity<double> pb;
return 0;
}
Well, I get the very well-known error:
Undefined symbols for architecture x86_64:
"Equity<double>::Equity()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have already changed in Build Settings the C++ standard library to libstdc++, also to default compiler, and so on. Do I have a problem with my project settings? Is perhaps the template wrongly implemented? I was thinking I should also have a instrument.cpp file, but then again definitions for templates must be kept in the header file so that would probably crash too.
Thanks in advance

You declared the default constructors for both Instrument and Equity but defined them nowhere.
Alter their definitions appropriately:
public:
Equity() = default; // Or {} in pre-C++11
// ^^^^^^^^^
(And equivalently for Instrument)
You can also completely omit the declarations of any default constructors for now since you didn't declare any other constructors in both Equity and Instrument and the default constructors will be generated automatically.

Related

Why virtual function has to be implemented in superclass?

I am trying to compile the following code:
#include <iostream>
class X{
public:
virtual void func();
};
class Y : public X{
public:
virtual void func(){
std::cout << "y" << std::endl;
}
};
int main(){
Y* y = new Y();
y->func();
return 0;
}
But building fails (on Xcode - C++11) with the following messages:
Undefined symbols for architecture x86_64:
"typeinfo for X", referenced from:
typeinfo for Y in c.o
"vtable for X", referenced from:
X::() in c.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, as soon as I add an implementation for func in X, it builds successfully. I am pretty sure, that virtual method is optional to be implemented in the superclass but I don't understand why is this happening. Also, if comment the code in main(), it builds successfully. I am assuming that the problem is calling the func() in main, but Xcode doesn't list it as runtime error, it only says build-time error.
If you don't want to implement the virtual function in the base class at all, simply mark it as pure virtual:
virtual void func() = 0;
No, you are wrong. You need to have implementations for non-pure virtual functions. If you do not want to provide an implementation, you need to make function pure virtual, using = 0 syntax.

Call Base Default constructor Template Class [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
The question is how to call the base constructor from an inherited template class. I want to create a FixedQueue and overload some function in std::queue. Therefore std:queue is the base class. The keyword using, since c++11, can be used to call the base and it works if this is a specialised class, but I cannot get it working with a template class.
Furthermore I tried it to use the old c++ standard in which I simply invoke the defined constructors in std::queue. However it doesn't work.
h file
#ifndef _HEADER_FIXED_QUEUE_
#define _HEADER_FIXED_QUEUE_
#include <queue>
#include <iostream>
template<class T>
class FixedQueue : public std::queue<T>
{
//using queue<T>::queue<T>;
public:
FixedQueue();
FixedQueue(const T &initial_var);
void foo() { std::cout << "inside\n"; }
};
#endif
cpp file
#include "FixedQueue.h"
template<typename T>
FixedQueue<T>::FixedQueue()
:
std::queue<T>()
{
std::cout << "Default Constructor FixedQueue\n";
}
template<typename T>
FixedQueue<T>::FixedQueue(const T &initial_var)
:
std::queue<T>(initial_var)
{
std::cout << "Specialized Constructor FixedQueue\n";
}
main file.
#include <iostream>
#include "FixedQueue.h"
int main()
{
FixedQueue<int> d_frameSlices;
std::cout << "I want to do something with my queue\n";
}
The question is thus. How do I chain the constructors to the defined constructors in the base class std::queue. The template thing is killing me.
This is the error message I obtain from clang, which is the usual undefined reference.
Undefined symbols for architecture x86_64:
"FixedQueue<int>::FixedQueue()", referenced from:
_main in main-lqoFSA.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If someone knows how to do this with "using" or the old fashion way I am happy with both. Thanks in advance
you should not put the template in cpp file put it all in header file

What is the syntax for object instantiation in C++?

when I compile the following c++ code:
#include "ConstantList.h"
using namespace std;
int main() {
ConstantList* cl = new ConstantList();
//do something with cl
delete cl;
cl = NULL;
return 0;
}
The compiler gives me the error:
Undefined symbols:
"ConstantList::~ConstantList()", referenced from:
_main in ccNfeeDU.o
"ConstantList::ConstantList()", referenced from:
_main in ccNfeeDU.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Am I not getting the syntax right for instantiating an object?
My ConstantList.h file looks like this:
#ifndef ConstantList_h
#define ConstantList_h
#include <string>
#include "Token.h"
using namespace std;
class ConstantListTail;
class ConstantList {
public:
ConstantList();
~ConstantList();
std::string toString();
void push_back(Token*);
void push_back(ConstantListTail*);
private:
Token* termString;
ConstantListTail* constantListTail;
};
#endif
Any help is greatly appreciated!
Your syntax is correct, because you are getting a linker error, not a compiler error. This error means that you are compiling your main without the source of the ConstantList.cpp, or linking without a reference to ConstantList.o
Compiling with this command should fix the error:
g++ collect2.cpp ConstantList.cpp
(I am assuming that the file with your main function is called collect2.cpp).
"undefined symbol" means you have declared the identifier (in this case the destructor), and it's used, but as far as the linker knows you have not defined it
add a definition somewhere, and make sure the compiled version is in one of the files the linker links
re "syntax for instantiation", unfortunately there is no dedicated syntax for that in C++
instead the functional cast notation is used for constructor invocations
perhaps the closest you get to a pure instantiation syntax is the new expression
re
using namespace std;
in a header file: don't.
for example, the standard library defines something called distance. what are the chances that some code that includes the header will have its own distance, and get a name collision? much higher than zero.
this doesn't mean you should never have using namespace std; in a header file, but you should never have it in the global namespace in a header file. and for other namespaces, be very aware of what that does, namely offering all the standard library names as part of also that namespace.

C++ Singleton in Xcode

I'm trying to make a Singleton class in C++ with Xcode. It's a really basic class and I get a linker error that I don't understand. Can any1 help please?
Here is the class header file :
#ifndef _NETWORK_H_
#define _NETWORK_H_
#include <iostream>
#include <list>
#include "Module.h"
using namespace std;
/*
* Assume only one network can run at a time
* in the program. So make the class a singleton.
*/
class Network {
private:
static Network* _instance;
list<Module*> _network;
public:
static Network* instance();
};
#endif
Here is the impl file :
#include "Network.h"
Network* Network::instance() {
if (!_instance)
_instance = new Network();
return _instance;
}
Here is the compiler error :
Undefined symbols for architecture x86_64:
"Network::_instance", referenced from:
Network::instance() in Network.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You need to declare actual storage for Network::_instance somewhere. Likely the impl. file.
Try adding to your impl file:
Network *Network::_instance=0;
You need to define your instance in the implementation file:
#include "Network.h"
Network *Network::_instance;
The static Network *_instance; declaration just says that there exists a Network::_instance somewhere. You must provide a single definition somewhere for it to actually exist.

GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'

I'm setting up a C++ project, on Ubuntu x64, using Eclipse-CDT. I'm basically doing a hello world and linking to a commerical 3rd party library.
I've included the header files, linked to their libraries, but I still get linker errors. Are there some possible problems here other than the obvious (e.g. I am 99% sure I'm linking to the correct library).
Is there a way to confirm the static libraries I am linking to are 64bit?
Is there a way to confirm that the library has the class (and methods) I am expecting it to have?
Eclipse says:
Building target: LinkProblem
Invoking: GCC C++ Linker
g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3
./src/LinkProblem.o: In function `main':
/home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()'
./src/LinkProblem.o: In function `SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()'
./src/LinkProblem.o: In function `~SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
collect2: ld returned 1 exit status
make: *** [LinkProblem] Error 1
This linker error usually (in my experience) means that you've overridden a virtual function in a child class with a declaration, but haven't given a definition for the method. For example:
class Base
{
virtual void f() = 0;
}
class Derived : public Base
{
void f();
}
But you haven't given the definition of f. When you use the class, you get the linker error. Much like a normal linker error, it's because the compiler knew what you were talking about, but the linker couldn't find the definition. It's just got a very difficult to understand message.
Assuming those methods are in one of the libs it looks like an ordering problem.
When linking libraries into an executable they are done in the order they are declared.
Also the linker will only take the methods/functions required to resolve currently outstanding dependencies. If a subsequent library then uses methods/functions that were not originally required by the objects you will have missing dependencies.
How it works:
Take all the object files and combine them into an executable
Resolve any dependencies among object files.
For-each library in order:
Check unresolved dependencies and see if the lib resolves them.
If so load required part into the executable.
Example:
Objects requires:
Open
Close
BatchRead
BatchWrite
Lib 1 provides:
Open
Close
read
write
Lib 2 provides
BatchRead (but uses lib1:read)
BatchWrite (but uses lib1:write)
If linked like this:
gcc -o plop plop.o -l1 -l2
Then the linker will fail to resolve the read and write symbols.
But if I link the application like this:
gcc -o plop plop.o -l2 -l1
Then it will link correctly. As l2 resolves the BatchRead and BatchWrite dependencies but also adds two new ones (read and write). When we link with l1 next all four dependencies are resolved.
Qt C++ will show this error when you change a class such that it now inherits from QObject (ie so that it can now use signals/slots). Running qmake -r will call moc and fix this problem.
If you are working with others via some sort of version control, you will want to make some change to your .pro file (ie add/remove a blank line). When everyone else gets your changes and runs make, make will see that the .pro file has changed and automatically run qmake. This will save your teammates from repeating your frustration.
The problem for me turned out to be pretty obscure. My class looked like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() { }
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
//-----------------------------------------
//-----------------------------------------
// main.h
class derived : public base {
public:
virtual int foo() ;
};
//-----------------------------------------
//-----------------------------------------
// main.cpp
int main () {
derived d;
}
//-----------------------------------------
The problem is in the linker. My header file went in a library somewhere, but all the virtual functions were declared 'inline' in the class declaration. Since there was no code using the virtual functions (yet), the compiler or linker neglected to put actual function bodies in place. It also failed to create the vtable.
In my main code where I derived from this class, the linker tried to connect my class to the base class and his vtable. But the vtable had been discarded.
The solution was to declare at least one of the virtual functions' bodies outside the class declaration, like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() ; //-- No longer declared 'inline'
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
base::~base()
{
}
//-----------------------------------------
In regards to problems with Qt4, I couldn't use the qmake moc option mentioned above. But that wasn't the problem anyway. I had the following code in the class definition:
class ScreenWidget : public QGLWidget
{
Q_OBJECT // must include this if you use Qt signals/slots
...
};
I had to remove the line "Q_OBJECT" because I had no signals or slots defined.
I had this error message. The problem was that I declared a virtual destructor in the header fileļ¼Œ but the virtual functions' body was actually not implemented.
This error will also occur when we simply declare a virtual function without any definition in the base class.
For example:
class Base
{
virtual void method1(); // throws undefined reference error.
}
Change the above declaration to the below one, it will work fine.
class Base
{
virtual void method1()
{
}
}
In my case the problem occured when i forgot to add the =0 on one function in my pure virtual class. It was fixed when the =0 was added. The same as for Frank above.
class ISettings
{
public:
virtual ~ISettings() {};
virtual void OKFunction() =0;
virtual void ProblemFunction(); // missing =0
};
class Settings : ISettings
{
virtual ~Settings() {};
void OKFunction();
void ProblemFunction();
};
void Settings::OKFunction()
{
//stuff
}
void Settings::ProblemFunction()
{
//stuff
}
I stumbled across the issue now, too. The application defined a pure virtual interface class and a user-defined class provided through a shared lib was supposed to implement the interface. When linking the application, the linker complained that the shared lib would not provide vtable and type_info for the base class, nor could they be found anywhere else.
Turned out that I simply forgot to make one of the interface's methods pure virtual (i.e. omitted the " = 0" at the end of the declaration. Very rudimentary, still easy to overlook and puzzling if you can't connect the linker diagnostic to the root cause.
I had this error message when trying "hello world" like things with Qt. The problems went away by correctly running the qt moc (meta object compiler) and compiling+including these moc-generated files correctly.
If you have a base class with pure virtual function, make sure your base class constructor and destructor has body otherwise linker fails.
I put this for future visitors:
if you are receiving the error on creating an Exception object, then the cause of it probably is a lack of definition for what() virtual function.