I'm working on a cpp programm using abstract classes. Apparently the compiler doesn't accept the fact that I declared the abstract class and the derived. I have different files (.cpp and .h). The errors are the following:
1>IGeomObj.obj : error LNK2005: "public: virtual void __thiscall IGeomObj::circumference(void)" (?circumference#IGeomObj##UAEXXZ) already defined in GeoRect.obj
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall GeoRect::circumference(void)" (?circumference#GeoRect##UAEXXZ)
1>IGeomObj.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
And here the code:
main()
# include <iostream>
# include "IGeomObj.h"
# include "GeoCircle.h"
# include "GeoEllipse.h"
# include "GeoRect.h"
# include "GeoSquare.h"
# include "GeoTriangle.h"
using namespace std;
int main()
{
/*GeoSquare *R;
GeoTriangle *R;
GeoRect *R;
GeoRect *R;*/
int opt;
do{
cout<<endl<<"Menu:"<<endl<<endl<<"0. Exit"<<endl<<"1. New rectangle"
<<endl<<"2. New Square"<<endl<<"3. New Triangle"<<endl<<"4. New Circle"<<endl
<<"5. New Ellipse"<<endl;
cin>>opt;
switch(opt)
{
case 0:
break;
case 1:
GeoRect *R=new GeoRect;
cout<<endl<<"Height of the rectangle: ";
cin>>R->h;
cout<<endl<<"Width of the rectangle: ";
cin>>R->b;
R->output();
break;
};
}while(opt!=0);
system("pause");
return 0;
}
IGeomObj.h
#pragma once
#ifndef IGEOMOBJ_H
#define IGEOMOBJ_H
#include <iomanip>
#include <fstream>
class IGeomObj{
public:
float b,h,r,f,u;
virtual void output()=0;
virtual void area()=0;
virtual void circumference()=0;
};
#endif
IGeomObj.cpp
#include "IGeomObj.h"
#include <iostream>
using namespace std;
void IGeomObj::output(){};
void IGeomObj::area(){};
void IGeomObj::circumference(){};
GeoRect.h
#pragma once
#ifndef GEORECT_H
#define GEORECT_H
#include <iomanip>
#include <fstream>
#include "IGeomObj.h"
class GeoRect:public IGeomObj
{
public:
virtual void output();
virtual void area();
virtual void circumference();
};
#endif
GeoRect.cpp
#include "GeoRect.h"
#include <iostream>
using namespace std;
void GeoRect::output()
{
cout<<"Rectangle Area: "<<this->f<<" Circumference: "<<this->u;
};
void GeoRect::area()
{
this->f=this->h*this->b;
};
void IGeomObj::circumference()
{
this->u=2*this->h+2*this->b;
};
Your GeoRect.cpp file implements IGeomObj::circumference(), which is legal as you can provide an implementation for a pure virtual function.
However this is not sufficient are you're not also implementing GeoRect::circumference(), which is required on account of the base class function being declared as a pure virtual function.
In GeoRect.cpp you have a definition for IGeomObj::circumference.
void IGeomObj::circumference()
{
this->u=2*this->h+2*this->b;
};
but this should be a definition for GeoRect instead.
void GeoRect::circumference()
{
this->u=2*this->h+2*this->b;
};
It's also not necessary to add this-> for every reference to a member.
void GeoRect::circumference()
{
u=2*h+2*b;
};
Related
I am working on a homework problem where we have to use inheritance. (I'm not very good with inheritance yet). We are to make a parent class "card_games" that has two children classes called "gofish" and "poker". We are given a template that our main has to follow, and the rest of the design is up to us. Here is my header file: (called "classes.h")
#include <vector>
using namespace std;
struct cards{
int rank;
char suit;
};
class players{
public:
int points;
int active;
vector<cards> cardhand;
void printhand(players *gameplayers, int person);
};
class card_games{
protected:
players *gameplayers;
void player_make();
public:
virtual void play();
};
class poker :public card_games{
public:
void play();
};
class gofish :public card_games{
public:
void play();
};
void player0_play(players *gameplayers, cards *cardlist, int people);
void createdeck(cards *cardlist);
void shuffle(cards *cardlist);
void deal(cards *cardlist, int people, players *gameplayers);
int getplayers();
I have determined the error is something to do with my virtual call. The error specifically is:
cardgames_play.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall card_games::play(void)" (?play#card_games##UAEXXZ)
And I believe this causes my next error of:
card_games.exe : fatal error LNK1120: 1 unresolved externals
Anyway something is wrong with my virtual void function.
Here is my main function:
#include <iostream>
#include "classes.h"
int main(){
card_games *game;
int opt;
game = NULL;
cout << "Poker 1, Go Fish 2" << endl;
cin >> opt;
if (opt == 1)
game = new poker;
else if (opt == 2)
game = new gofish;
game->play();
return 0;
}
We are supposed to roughly use this template. If I understand it correctly, I am creating an instance of Card_game class called game, then assigning game to an instance of either gofish or poker. Then I dereference "game" to the "play();" function. The rest of my code, I have a
void gofish::play(){
blah blah
}
and a
void poker::play(){
blah blah
}
Which have the rest of my code that works.
Any help regarding this error is greatly appreciated. Thanks!
P.S. I am using visual studio 2013 on windows 8.
The method void play(); in card_games does not have a body, and it is not pure virtual. Just do the change:
class card_games{
protected:
players *gameplayers;
void player_make();
public:
virtual void play()=0; //make it pure virtual
};
I am trying to run a function from a class file, but it is not working and I get the the following error messages:
error LNK1120: 1 unresolved externals
error LNK2019: unresolved external symbol "public: void __thiscall NS::Class1::test(void)" (?test#Class1#NS##QAEXXZ) referenced in function _main
//Main.cpp
#include<iostream>
#include<string>
#include<Windows.h>
#include "Class1.h"
int main(){
NS::Class1 E;
E.test();
return 0;
};
//Class1.cpp
#include <Windows.h>
#include <string>
namespace NS{
class Class1{
Class1(){
OutputDebugString(L"Created.");
}
void test(){
OutputDebugString(L"Hello World");
}
};
}
//Class1.h
#ifndef _Class1_H_
#define _Class1_H_
namespace NS{
class Class1{
public:
void test();
};
}
#endif
In your source file, you're redefining the class, rather than defining its member functions. That will give undefined behaviour, since you're only allowed to define the class once. The source file should look more like:
#include "Class1.h"
#include <Windows.h>
NS::Class1::Class1(){
OutputDebugString(L"Created.");
}
void NS::Class1::test(){
OutputDebugString(L"Hello World");
}
You'll also need to modify the class definition in the header, since it doesn't declare a constructor.
Also, make sure that your project is compiling and linking both source files.
Your header file contains reserved IDs for the include guard and misses the declaration of the constructor. It should look like this:
#ifndef CLASS1_H
#define CLASS1_H
namespace NS {
class Class1
{
public:
Class1();
void test();
};
}
#endif
The definition of the class should not include the class declaration, it should include it, and should look more like this:
#include <Windows.h>
#include "Class1.h"
namespace NS {
Class1::Class1()
{
OutputDebugString(L"Created.");
}
void Class1::test()
{
OutputDebugString(L"Hello World");
}
}
I think your .cpp file might be causing the issue. Since you already created the class definition in your header with class member declarations, just import the Class1.h header in the Class1.cpp file and scope the member functions then defining their behavior.
so maybe try:
#include <Class1.h>
NS::Class1::Class1(){}//constructor
void NS::Class1::test(std::cout << "hi"){}
//class1.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
class class1
{
public:
int var;
class1(int i)
{
var = i;
}
};
//class1.h:
#include <iostream>
#include <stdlib.h>
using namespace std;
class class1
{
public:
int var;
class1(int i = 0);
};
//main.cpp
#include <iostream>
#include <stdlib.h>
#include "class1.h"
using namespace std;
int main()
{
class1 a(5);
return 0;
}
error:
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall class1::class1(int)" (??0class1##QAE#H#Z) referenced in function _main
what the heck is going on? I swear I've made almost the exact same program before and It's worked.
Change class1.cpp to something like:
//class1.cpp
#include "class1.h"
class1::class1(int i) : var(i) {}
You don't want to define the class itself again -- just define the member functions in the implementation file.
Then you'll build it something like:
g++ main.cpp class1.cpp
[of course, substituting the correct compiler name for the compiler you're using]
Most likely you are not compiling both cpp files. Check your build settings and make sure that both main.cpp and class1.cpp are being compiled.
However you also have a serious problem. You are declaring class1 twice. Once in the header:
class class1
{
public:
int var;
class1(int i = 0);
};
... and again in the cpp:
class class1
{
public:
int var;
class1(int i)
{
var = i;
}
};
In C++ there should be exactly one declaration for a class (and exactly one definition).
The way it works is you declare the class in your header, as you have already done, and then you define the members in the cpp, like this:
class1.cpp
#include "class1.h"
class1::class1(int i)
{
var = i;
}
Please have a look at the following code
Main.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
system("pause");
return 0;
}
Magic.h
#pragma once
class Magic
{
public:
Magic();
~Magic();
virtual void display()=0;
};
Spell.h
#pragma once
#include "Magic.h"
#include <iostream>
#include <string>
using namespace std;
class Spell :
public Magic
{
public:
Spell(void);
Spell(string words);
~Spell(void);
void display();
private:
string words;
};
Spell.cpp
#include "Spell.h"
#include "Magic.h"
#include <iostream>
#include <string>
using namespace std;
Spell::Spell(void)
{
}
Spell::Spell(string words)
{
this->words = words;
}
Spell::~Spell(void)
{
cout << "Delete Spell" << endl;
}
void Spell::display()
{
cout << "Spell Words: " << words << endl;
}
Here, I am getting the error
1>------ Build started: Project: Revision1_1, Configuration: Debug Win32 ------
1>Spell.obj : error LNK2019: unresolved external symbol "public: __thiscall Magic::~Magic(void)" (??1Magic##QAE#XZ) referenced in function __unwindfunclet$??0Spell##QAE#XZ$0
1>Spell.obj : error LNK2019: unresolved external symbol "public: __thiscall Magic::Magic(void)" (??0Magic##QAE#XZ) referenced in function "public: __thiscall Spell::Spell(void)" (??0Spell##QAE#XZ)
1>C:\Users\yohan\Documents\Visual Studio 2010\Projects\Revision1_1\Debug\Revision1_1.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I do not understand what to do here. Why is this happening? Please help! I am new to C++ anyway..
Magic is not implementing its constructor and destructor (which also should be virtual).
Don't even declare the constructor if not necessary, e.g.
class Magic {
public:
virtual ~Magic() {}
virtual void display() = 0;
};
Unrelated: I didn't know you can display magic.
You didn't implement
Magic();
~Magic();
You'll need to either implement them inline, in an implementation file, or mark them = default.
You have declared a destructor in your Magic class but did not define it. That's why the linker complains (and the compiler doesn't).
You don't have an implementation for Magic. If your intention is for Magic to be an abstract base class, then just change its declaration to:
#pragma once
class Magic
{
public:
virtual void display()=0;
};
Remember, any method that is not followed by = 0 in the interface must be implemented in the class.
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.