When I attempted to specialize one of my template functions, Visual Studio threw me an external error, including an error for a function that was not specialized.
The three errors:
1>------ Build started: Project: Project3, Configuration: Debug Win32 ------
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::reverse(void)" (?reverse#?$linearList#VFriendToken####UAEXXZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::print(void)" (?print#?$linearList#VFriendToken####UAEXXZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::insertionSort(void)" (?insertionSort#?$linearList#VFriendToken####UAEXXZ)
Here is the relevant part of the code:
template<class T>
class arrayList : public linearList<T>
{
public:
//other methods
void reverse();
void print();
void insertionSort();
};
template<class T>
void arrayList<T>::reverse()
{
//method body
}
template<>
void arrayList<FriendToken>::insertionSort()
{
//method body
}
template<>
void arrayList<FriendToken>::print()
{
//method body
}
template<class T>
void arrayList<T>::insertionSort(){}
template<class T>
void arrayList<T>::print(){}
Your example shows specializations of the arrayList member functions which I assume are supposed to be overriding their virtual equivalants in linearList. The linker is saying it cant find the virtual members in the class linearList which is not included in your example.
virtual void __thiscall linearList<class FriendToken>::reverse(void)
If I add a definition of linearList like this the linker is quiet (on MSVC2010, I also added a empty FriendToken class to make things work).
template<typename T>
class linearList
{
public:
virtual void reverse() = 0; //pure virtual
virtual void print() = 0;
virtual void insertionSort() = 0;
};
If this is not your problem please post the code for linearList and I will update my answer as that is surely the source of your problem.
If needed for reference here is how I used the function reverse to test:
arrayList<FriendToken> a;
static_cast<linearList<FriendToken>&>(a).reverse();
Related
Here's my abstract class Storestate.h:
#ifndef STORESTATE_H_
#define STORESTATE_H_
class Store;
class StoreState
{
public:
virtual void Close(Store&);
virtual void Open(Store&);
virtual void Sell(Store&);
};
#endif
The Derived class header file ConcreteStateOpened.h:
#ifndef CONCRETESTATEOPENED_H_
#define CONCRETESTATEOPENED_H_
#include "StoreState.h"
#include "Store.h"
class ConcreteStateOpened : public StoreState
{
public:
ConcreteStateOpened() {}
void Open(Store&) override;
void Close(Store&) override;
void Sell(Store&) override;
};
#endif
The Dervied class cpp file ConcreteStateOpened.cpp:
#include "ConcreteStateOpened.h"
#include <iostream>
using namespace std;
void ConcreteStateOpened::Open(Store &store)
{
cout << store.Name << " is already opened!" << endl;
}
void ConcreteStateOpened::Close(Store &store)
{
store.State = ConcreteStateOpened();
}
void ConcreteStateOpened::Sell(Store &store)
{
std::cout << "Sell Opened";
}
I don't know how to fix this. I tried removing override keywords, aswell as virtual ones. Even removing the definition etc. I just need help from pros :,)
Here are the unresolved external symbol errors:
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>D:\Local-Git-Repos\DesignPatterns\StateC++\StateStore\Debug\StateStore.exe : fatal error LNK1120: 3 unresolved externals
You didn't make the methods in the abstract base pure virtual.
Also you should add : public virtual destructor, protected default constructor and remove copy/move/assignment constructors
#ifndef STORESTATE_H_
#define STORESTATE_H_
class Store;
class StoreState
{
public:
virtual ~StoreState() = default;
StoreState(const StoreState&) = delete;
StoreState(StoreState&&) = delete;
StoreState& operator=(const StoreState&) = delete;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
protected:
StoreState() = default; // prevent accidental creation
};
#endif
Your StoreState isn't actually abstract. You have declared Close, Open, Sell as actual virtual functions with definitions. To declare a virtual function with no definition in that class, use the "pure virtual" syntax = 0.
Also, it's best practice for a polymorphic class type to have a virtual destructor. And per the Rule Of Five, when you declare a destructor, be sure to think about the copy/move constructor and copy/move assignment. For an interface class, it's often best to just make it uncopyable and unassignable.
class StoreState
{
public:
StoreState() = default;
StoreState(const StoreState&) = delete;
StoreState& operator=(const StoreState&) = delete;
virtual ~StoreState() = default;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};
For starters there is no abstract class in the presented code by you because the class StoreState does not contain pure virtual functions.
From the C++ 20 Standard (11.7.3 Abstract classes)
2 A virtual function is specified as a pure virtual function by using
a pure-specifier (11.4) in the function declaration in the class
definition. [Note: Such a function might be inherited: see below. —
end note] A class is an abstract class if it has at least one pure
virtual function. [Note: An abstract class can be used only as a
base class of some other class; no objects of an abstract class can be
created except as subobjects of a class derived from it (6.2, 11.4). —
end note] A pure virtual function need be defined only if called with,
or as if with (11.4.6), the qualified-id syntax
You need either to provide definitions of the virtual functions declared in the class StoreState or to make them pure virtual functions like for example
class StoreState
{
public:
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};
Even if a function is declared as a pure virtual function nevertheless you may provide its definition (outside the class definition where it is declared as a pure virtual function) if it is required.
Pay attention to that when you have polymorphic classes then you should declare the destructor also as virtual. For example
class StoreState
{
public:
virtual ~StoreState() = default;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};
You may need to add virtual to the concrete class methods
#ifndef CONCRETESTATEOPENED_H_
#define CONCRETESTATEOPENED_H_
#include "StoreState.h"
#include "Store.h"
class ConcreteStateOpened : public StoreState
{
public:
ConcreteStateOpened() {}
virtual void Open(Store&) override;
virtual void Close(Store&) override;
virtual void Sell(Store&) override;
};
#endif
I have a class like
template <class T>
class LinkedListItem
{
public:
LinkedListItem(T value);
LinkedListItem(const LinkedListItem<T>& rhs);
T getValue(void);
LinkedListItem<T>& getNext(void);
void setNext(LinkedListItem<T>& next);
LinkedListItem<T>& operator=(const LinkedListItem<T>& rhs);
~LinkedListItem();
private:
T _value;
LinkedListItem& _next;
};
I am trying to write a unit test like
TEST_CLASS(LinkedListUnitTests)
{
public:
TEST_METHOD(Add_to_An_Empty_Linked_List)
{
LinkedListItem<int> item(1);
}
//private:
};
When I try to just build the above code I get the ugly error -
error LNK2019: unresolved external symbol "public: __thiscall cpp::libraries::datastructures::LinkedListItem::LinkedListItem(int)" (??0?$LinkedListItem#H#datastructures#libraries#cpp##QAE#H#Z) referenced in function "public: void __thiscall CppLibrariesTests::LinkedListUnitTests::Add_to_An_Empty_Linked_List(void)" (?Add_to_An_Empty_Linked_List#LinkedListUnitTests#CppLibrariesTests##QAEXXZ)
I am using Visual Studio 2012.
Interestingly, If I add template in the unit test class like below the compile error goes away but the tests are not discovered and I can't run them.
template<class T>
TEST_CLASS(LinkedListUnitTests){..}
I am trying to pick up C++ after a long time so I won't be surprised if I am doing something very stupid. Any thoughts anyone?
Templates must ideally be implemented inline. Second pass of compiler cannot re use the CPP file that has the implementation. Or, you need to #include the CPP file also.
Refer this article
I am looking for the source of the error since a few hours without success. My project consists of two sub projects. The first one is a dll and the second one is an application (exe).
I simplified my original code, which is part of the dll:
#ifndef blub_base
#define blub_base
#include "SomeInterface.hpp"
#include "Object.hpp"
#include <map>
namespace a
{
namespace b
{
class __declspec(dllexport) CBase : public CSomeInterface
{
protected:
CBase() {}
public:
CBase(SomeDifferentObject* f_object_p) { /* concrete implementation in cpp */ }
~CBase() { /* concrete implementation in cpp */ }
bool initialize() { /* concrete implementation in cpp */ }
bool shutdown() { /* concrete implementation in cpp */ }
void foo() { /* concrete implementation in cpp */ }
virtual void blubblub(Object* f_object_p) { /* concrete implementation in cpp */ }
protected:
bool blub1(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const { /* concrete implementation in cpp */ }
bool blub2(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const { /* concrete implementation in cpp */ }
void blub3(Object* f_object_p) const { /* concrete implementation in cpp */ }
};
}
}
#endif
#ifndef blub
#define blub
#include "Base.hpp"
namespace a
{
namespace b
{
class __declspec(dllexport) CChild : public CBase
{
private:
CChild() {}
public:
CChild(SomeDifferentObject* f_object_p) { /* concrete implementation in cpp */ }
/// deconstructor
~CChild() { /* concrete implementation in cpp */ }
void blubblub(Object* f_object_p) override { /* concrete implementation in cpp */ }
protected:
bool blub1(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const override { /* concrete implementation in cpp */ }
bool blub2(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const override { /* concrete implementation in cpp */ }
void blub3(Object* f_object_p) const override { /* concrete implementation in cpp */ }
};
}
}
#endif
If I am trying to instantiate a CChild object in my application I get linker errors for all functions of the CChild class:
Error 75 error LNK2001: unresolved external symbol "public: virtual void __thiscall a::b::CChild::blubblub(class a::b::Object *)" (?blubblub#CChild#b#a##UAEXPAVObject#23##Z) application.obj Application
Error 74 error LNK2019: unresolved external symbol "public: virtual __thiscall a::b::CChild::~CChild(void)" (??1CChild#b#a##UAE#XZ) referenced in function "public: virtual void * __thiscall a::b::CChild::`vector deleting destructor'(unsigned int)" (??_ECChild#b#a##UAEPAXI#Z) Application.obj Application
Error 73 error LNK2019: unresolved external symbol "public: __thiscall a::b::CChild::CChild(class a::b::SomeDifferentObject *)" (??0CChild#b#a##QAE#PAVSomeDifferentObject#12##Z) referenced in function _main Application.obj Application
Error 77 error LNK2001: unresolved external symbol "protected: virtual bool __thiscall a::b::CChild::blub1(class Object *,class std::map,class std::allocator > > &)const " (?blub1#CChild#b#a##MBE_NPAVObject#23#AAV?$map#KIU?$less#K#std##V?$allocator#U?$pair#$$CBKI#std###2##std###Z) Application.obj Application
Error 76 error LNK2001: unresolved external symbol "protected: virtual bool __thiscall a::b::CChild::blub2(class Object *,class std::map,class std::allocator > > &)const " (?blub2#CChild#b#a##MBE_NPAVObject#23#AAV?$map#KIU?$less#K#std##V?$allocator#U?$pair#$$CBKI#std###2##std###Z) Application.obj Application
Error 78 error LNK2001: unresolved external symbol "protected: virtual void __thiscall a::b::CChild::blub3(class a::b::Object *)const " (?blub3#CChild#b#a##MBEXPAVObject#23##Z) Application.obj Application
I am using Visual Studio and all cpp files are in the project (checked many times). Each function is implemented e.g.
CChild::CChild(SomeDifferentObject* f_object_p) : CBase(f_object_p)
{
}
It seems that the relevant cpp files are not found?!
Thank you very much for your help!
Kind regards,
Bobby
It is not working because classes are always exported. They need to be exported by dll project and imported by projects that use that dll.
To fix this, add header file, for example ab_dll.h and there:
#ifdef AB_DLL_EXPORT
#define AB_DLL_API __declspec(dllexport)
#else
#define AB_DLL_API __declspec(dllimport)
#endif
Then use that macro in your classes:
class AB_DLL_API CBase : public CSomeInterface
{
//...
};
class AB_DLL_API CChild : public CBase
{
//...
};
Also in your VS dll project add AB_DLL_EXPORT in PreprocessorDefinitions so that the classes are exported. This works that way that if AB_DLL_EXPORT is defined in the project then classes will be exported, otherwise will be imported.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ template, linking error
I have two linking errors and I have no idea what's wrong with the code and how to fix them:
main.obj:-1: error: LNK2019: unresolved external symbol "public:
__thiscall A::A(void)" (??0?$A#VB####QAE#XZ) referenced in function "public: __thiscall B::B(void)" (??0B##QAE#XZ)
and
main.obj:-1: error: LNK2019: unresolved external symbol "public: void
__thiscall A::exec(void (__thiscall B::*)(void))" (?exec#?$A#VB####QAEXP8B##AEXXZ#Z) referenced in function "public:
void __thiscall B::run(void)" (?run#B##QAEXXZ)
Explaining the code a little:
This class has to execute a function from the derived class. function exec is called from the derived class with a function from the derived class parameter. Signature of this function is void function();
//header.h
#ifndef HEADER_H
#define HEADER_H
template <class T>
class A
{
public:
typedef void (T::*ExtFunc)();
A();
void funcA();
void exec(ExtFunc func);
};
#endif // HEADER_H
//header.cpp
#include "header.h"
template<typename T>
A<T>::A() { }
template<typename T>
void A<T>::funcA()
{
cout << "testA\n";
}
template<typename T>
void A<T>::exec(ExtFunc func)
{
(T().*func)();
}
In main.cpp I derive a class from A class and pass the derived class as template paramtere. Then I execute function exec through the run() function.
//main.cpp
#include <iostream>
#include "header.h"
using namespace std;
class B : public A<B>
{
public:
B() { }
void run()
{
exec(&B::funcB);
}
void funcB()
{
cout << "testB\n";
}
};
int main()
{
B ob;
ob.run();
return 0;
}
Can anyone tell me what's going on?...
When you are using templates, generally you cannot put the implementation in a .cpp file - you have to put the whole class in the header. So move all the code from header.cpp to the .h.
You can get around this by doing an explicit instantiation inside the .cpp file - instantiating the template for a particular type. But this requires that you know ahead of time which types will need an instantiation and will prevent you from adding new instantiations. The only benefit is a reduction in compile time.
1>main.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::getfirst(int &)" (?getfirst#?$LinkedSortedList#H##UAE_NAAH#Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall LinkedSortedList<int>::clear(void)" (?clear#?$LinkedSortedList#H##UAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall LinkedSortedList<int>::print(void)const " (?print#?$LinkedSortedList#H##UBEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::insert(int)" (?insert#?$LinkedSortedList#H##UAE_NH#Z) referenced in function _main
1>main.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::find(int)const " (?find#?$LinkedSortedList#H##UBE_NH#Z)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall LinkedSortedList<int>::size(void)const " (?size#?$LinkedSortedList#H##UBEHXZ)
1>c:\users\chris\documents\visual studio 2010\Projects\lab0\Debug\lab0.exe : fatal error LNK1120: 6 unresolved externals
This is what I recieve when trying to compile my code. I've narrowed it down to (i believe) this section of code here:
#ifndef _LinkedSortedListClass_
#define _LinkedSortedListClass_
#include "LinkedNode.h"
#include "SortedList.h"
template <class Elm>
class LinkedSortedList: public SortedList<int> {
public:
void clear();
bool insert(Elm newvalue);
bool getfirst(Elm &returnvalue);
void print() const;
bool find(Elm searchvalue) const;
int size() const;
private:
LinkedNode<Elm>* head;
};
#endif
This is the child class of the SortedList, which is this, in case it's needed..
#ifndef _SortedListClass_
#define _SortedListClass_
template <class Elm> class SortedList {
public:
// -------------------------------------------------------------------
// Pure virtual functions -- you must implement each of the following
// functions in your implementation:
// -------------------------------------------------------------------
// Clear the list. Free any dynamic storage.
virtual void clear() = 0;
// Insert a value into the list. Return true if successful, false
// if failure.
virtual bool insert(Elm newvalue) = 0;
// Get AND DELETE the first element of the list, placing it into the
// return variable "value". If the list is empty, return false, otherwise
// return true.
virtual bool getfirst(Elm &returnvalue) = 0;
// Print out the entire list to cout. Print an appropriate message
// if the list is empty. Note: the "const" keyword indicates that
// this function cannot change the contents of the list.
virtual void print() const = 0;
// Check to see if "value" is in the list. If it is found in the list,
// return true, otherwise return false. Like print(), this function is
// declared with the "const" keyword, and so cannot change the contents
// of the list.
virtual bool find(Elm searchvalue) const = 0;
// Return the number of items in the list
virtual int size() const = 0;
};
#endif
Thanks so much for any help; our last class taught us nothing of inheritance, but this is project #1 for this class, without being taught inheritance here either, so this is all touch and go for me, despite what I managed to look up on Google.
Your methods aren't defined. So the linker is complaining because it can't link to their definitions.
Maybe it helps if you placed the definitions of your functions in your header file. This makes it easier for the compiler to resolve these external symbols.
I hope this will help.
Regards,
Philinator