I have a class SourceComponent, and its derived class, PeriodicSourceComponent.
Implementations are:
class SourceComponent : public Component
{
protected:
friend class UserInterface;
friend void readInput();
public:
virtual int returnType();
virtual int propagateLogic();
virtual void sourcePropagation(float);
virtual void accept(VisitorSources&);
SourceComponent();
};
and
#include "source_component.h"
class PeriodicSourceComponent : public SourceComponent
{
private:
int frequency;
friend void main();
friend void readInput();
friend class UserInterface;
public:
void sourcePropagation(float);
int returnType();
PeriodicSourceComponent();
};
When I try in some different class/method to do:
SourceComponent* s = new PeriodicSourceComponent;
it won't let me, sayin "a value of type periodicblabla cant be assigned to value of type sourceblabla". Why?
Edit:
Ok, in my main it looks lke this:
#include "source_component.h"
#include "periodic_source_component.h"
void main()
{
SourceComponent* s = new PeriodicSourceComponent;
}
And implementations of both classes:
source.cpp:
#include "source_component.h"
SourceComponent::SourceComponent()
{
outputState = -1;
}
int SourceComponent::propagateLogic()
{
return 1;
}
int SourceComponent::returnType()
{
return 5;
}
and periodic.cpp
#include "periodic_source_component.h"
PeriodicSourceComponent::PeriodicSourceComponent()
{
outputState = 0;
}
int PeriodicSourceComponent::returnType()
{
return 3;
}
void PeriodicSourceComponent::sourcePropagation(float time)
{
float t = time, period;
period = 1000000/frequency;
if(t > period)
{
while(t >= period)
t -= period;
}
if(t <= (period/2))
outputState = 0;
else
outputState = 1;
}
and its not working... (outputState is a member of class Component, base class of SourceComponent)
and the error message: A value of type "PeriodicSourceComponent*" cannot be assigned to a value of type "SourceComponent*".
Important Edit
When I try to compile, the actual compiler error is at PeriodicSourceComponent declaration, it says: "Base class undefined".
and also, I have two other derived classes from SourceComponent, but I don't see how they could interfere with this one..
EDIT 4
Ok so I figured out what causes the error, you were right of course, it something else I didn't post. I have class VisitorSources, heres definition:
#ifndef __VISITOR_SOURCES_H__
#define __VISITOR_SOURCES_H__
#include "component.h"
#include "impulse_source_component.h"
#include "arbitrary_source_component.h"
#include "periodic_source_component.h"
class VisitorSources
{
protected:
VisitorSources();
public:
virtual void visitImpulseSource(ImpulseSourceComponent*);
virtual void visitArbitrarySource(ArbitrarySourceComponent*);
virtual void visitPeriodicSource(PeriodicSourceComponent*);
void visitSource(int, float);
};
#endif
And its implementation is not yet written:
#include "visitor_sources.h"
void visitSource(int type, float time)
{
}
void VisitorSources::visitArbitrarySource(ArbitrarySourceComponent* a)
{
}
When I comment out the entire Visitor class and implementation, the above-mentioned errors are gone for some reason. I have no idea why...
The only error that remains is that when I try to use s->frequency, it says that frequency is not a member of SourceComponent, which is true, but it is a member of PeriodicSourceComponent, which is why I used the cast in the first place..
Finally, here's the Component class, the main class for all almost all other classes in the project :P
#ifndef __COMPONENT_H__
#define __COMPONENT_H__
#include <iostream>
#include <vector>
class Component
{
friend class UserInterface;
friend void readAndSimulate();
protected:
Component();
int numOfInputs;
int numOfOutputs;
std::vector<Component*> inputs;
std::vector<Component*> outputs;
friend void main();
float lengthOfSimulation;
int typeIfSource;
public:
int outputState;
virtual int propagateLogic() = 0;
virtual int returnType();
int beginPropagation();
virtual void sourcePropagation(float);
~Component();
};
#endif
And implementation:
#include "component.h"
#include <conio.h>
Component::Component()
{
}
int Component::beginPropagation()
{
std::vector<Component*>::const_iterator iter = outputs.begin();
for(;iter<outputs.end();++iter)
{
if ((*iter)->outputState == -2)
{
(*iter)->outputState = outputState;
return (*iter)->outputState;
}
}
std::vector<Component*>::const_iterator it = outputs.begin();
int finishedCycle, x;
while(1)
{
finishedCycle = 1;
for(; it < outputs.end(); ++it)
{
x = (*it)->propagateLogic();
if(!x)
finishedCycle = 0;
}
if(finishedCycle) break;
it = outputs.begin();
}
it = outputs.begin();
for(;it<outputs.end();++it)
(*it)->beginPropagation();
}
int Component::returnType()
{
return 0;
}
void Component::sourcePropagation(float)
{
}
Component::~Component()
{
std::vector<Component*>::const_iterator it = inputs.begin();
for(; it < inputs.end(); ++it)
{
if((*it) != NULL)
{
delete *it;
Component* p = *it;
p = NULL;
}
}
it = outputs.begin();
for(; it < inputs.end(); ++it)
{
if((*it) != NULL)
{
delete *it;
Component* p = *it;
p = NULL;
}
}
}
Are you using include guards in all your header files?
Not having them can cause the kinds of problems you're seeing.
Three guesses:
You copied and pasted code between header files and forgot to change the #include guards.
You use precompiled headers and included something before the #include "stdafx.h".
If you use precompiled headers, try deleting the .pch file.
Related
This question already has answers here:
Virtual/pure virtual explained
(12 answers)
Closed 1 year ago.
booking.h
#ifndef _BOOKING_H_
#define _BOOKING_H_
#include <string>
class Event {
private:
std::string event_option;
public:
Event(std::string event_option);
virtual ~Event();
void list_specific_event_details();
virtual void list_details();
};
class Films : public Event {
private:
std::string movie_option;
public:
Films(std::string movie_option);
void list_details();
};
class Live_Music : public Event {
private:
std::string live_music_option;
public:
Live_Music(std::string live_music_option);
void list_details();
};
class Standup_Comedy : public Event {
private:
std::string comedy_option;
public:
Standup_Comedy(std::string comedy_option);
void list_details();
};
#endif
booking.cpp
#include "booking.h"
#include <string>
Event::Event(std::string event_option)
{
this->event_option = event_option;
}
Event::~Event()
{
}
void Event::list_specific_event_details()
{
return list_details();
}
Films::Films(std::string movie_option) : Event("Films")
{
this->movie_option = movie_option;
}
void Films::list_details()
{
//some code ...
return;
}
Live_Music::Live_Music(std::string live_music_option) : Event("Live_Music")
{
this->live_music_option = live_music_option;
}
void Live_Music::list_details()
{
//some code...
return;
}
Standup_Comedy::Standup_Comedy(std::string comedy_option) : Event("Standup_Comedy")
{
this->comedy_option = comedy_option;
}
void Standup_Comedy::list_details()
{
//some code...
return;
}
main.cpp
#include "booking.h"
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector <Event *> choice;
choice.push_back(new Films("f"));
choice.push_back(new Live_Music("l"));
choice.push_back(new Standup_Comedy("s"));
for(unsigned i = 0; i < choice.size(); i++)
{
choice[i] -> list_specific_event_details();
}
for (Event * e: choice) delete e;
choice.clear();
}
I have written the above block of codes and got an error when I tried to compile it.
The error is as follows:
usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccuWXzBM.o:booking.cpp:(.rdata$_ZTV5Event[_ZTV5Event]+0x20): undefined reference to `Event::list_details()'
collect2: error: ld returned 1 exit status
Why am I getting this error, and how can I solve it?
You have not defined your method Event::list_details(). If you only want to declare the function but do not want to implement it, that is what is called an Interface, you can make it a pure virtual method with:
class Event
{
...
virtual void list_details() = 0;
...
};
This is my enum header file
//use like PostionType::President
enum PositionType
{ President,
VicePresident,
Secretary,
Treasurer,
Normal
};
And in my Ballot paper header and cpp file
#include <list>
#include <iostream>
#include "Candidate.h"
#include "PositionType.h" //include enum
class BallotPaper
{
private:
PositionType _positionbp;
std::list<Candidate> _candidatesbp;
public:
BallotPaper();
void setPositionBP(PositionType positionbp);
PositionType getPositionBP();
void setCandidateBP(std::list<Candidate> candidatesbp);
std::list<Candidate> getCandidateBP();
Candidate getCandidate(int index);
void ShowCandidates();
~BallotPaper();
};
#include "BallotPaper.h"
#include <string>
#include <iostream>
void BallotPaper::setPositionBP(PositionType positionbp)
{
_positionbp = positionbp;
}
PositionType BallotPaper::getPositionBP()
{
return _positionbp;
}
void BallotPaper::setCandidateBP(std::list<Candidate> candidatesbp)
{
_candidatesbp = candidatesbp;
}
std::list<Candidate> BallotPaper::getCandidateBP()
{
return _candidatesbp;
}
void BallotPaper::ShowCandidates()
{
for(Candidate c : _candidatesbp)
{
c->IncreaseVoteCount(); //ERROR!!!!
}
}
and this will be my candidate header and cpp file
class Candidate:public Member
{
private:
int _votecount;
PositionType _position;
public:
Candidate(std::string name, int id, std::string course, int contact, std::string joindate, PositionType currentposition) ;
~Candidate();
void setVoteCount(int votecount);
int getVoteCount();
void setPosition(PositionType position);
PositionType getPosition();
void IncreaseVoteCount(); //increase _votecount
};
#include "Candidate.h"
Candidate::Candidate()
{
_votecount = 0;
}
void Candidate::setVoteCount(int votecount)
{
_votecount = votecount;
}
int Candidate::getVoteCount()
{
return _votecount;
}
void Candidate::setPosition(PositionType position)
{
_position = position;
}
PositionType Candidate::getPosition()
{
return _position;
}
void Candidate::IncreaseVoteCount()
{
_votecount++;
}
I know is a super long code, and I appreciate for your patience in looking through it. My error is that it seems that it cannot recognize the function of "IncreaseVoteCount" in 'Candidate c'.
I have try to double check the syntax and the code for multiple times but i still don't understand what is the error here.
Sorry for the lack of a descriptive title.
I'm getting an error "one or more multiply defined symbols found"; to be more specific, I'm getting 46 of them. One for each function in my header/source files. Using Visual Studios 2013.
Here is the relevant source code:
augments.h
#ifndef AUGMENTS_H_
#define AUGMENTS_H_
namespace Augments {
// only used for pass-ins for constructors
enum class Weapon_Type {
sword
};
enum class Head_Type {
head
};
enum class Body_Type {
body
};
// the player (Monster) has a head, body and weapon
// that augments his abilities. This will mostly
// be the thing that draws to the screen for each
// augmentation, but more importantly it contains
// specific statistics about each one.
// So if there was a body that was able to fly,
// there would be a bool that denotes this ability.
class Head : public Actor {
const Head_Type type;
public:
Head(Head_Type);
void Update(float dt);
};
class Body : public Actor {
const Body_Type type;
public:
Body(Body_Type);
void Update(float dt);
};
class Weapon : public Actor {
const Weapon_Type type;
public:
Weapon(Weapon_Type);
void Update(float dt);
};
}
using AugHead = Augments::Head;
using AugBody = Augments::Body;
using AugWep = Augments::Weapon;
#endif
augments.cpp
#include "stdafx.h"
#include "Angel.h"
#include "Augments.h"
#include "LD33.h"
Augments::Head::Head(Augments::Head_Type x) : type(x) {
switch ( x ) {
case Head_Type::head:
SetSprite("Images\\head.png");
break;
};
};
void Augments::Head::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,40)).Y);
};
Augments::Body::Body(Augments::Body_Type x) : type(x) {
switch ( x ) {
case Body_Type::body:
SetSprite("Images\\body.png");
break;
};
}
void Augments::Body::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y);
}
Augments::Weapon::Weapon(Augments::Weapon_Type x ) : type(x) {
switch ( x ) {
case Weapon_Type::sword:
SetSprite("Images\\weapon.png");
break;
}
}
void Augments::Weapon::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,-40)).Y);
}
monster.h
// monster related
#include "Augments.h"
#include "Angel.h"
#ifndef MONSTER_H_
#define MONSTER_H_
namespace Player {
// contains information like health attack etc
// but more important body types
class Monster : public PhysicsActor {
int max_health, curr_health;
int attack_damage;
Augments::Head* frame_head;
Augments::Weapon* frame_weapon;
Augments::Body* frame_body;
public:
void Refresh(float dt);
int R_Max_Health() const;
int R_Curr_Health() const;
int R_Attack_Damage() const;
Augments::Head* R_Frame_Head();
Augments::Weapon* R_Frame_Weapon();
Augments::Body* R_Frame_Body();
void Set_Max_Health(int);
void Set_Curr_Health(int);
void Add_Curr_Health(int);
void Set_Attack_Damage(int);
// will automatically remove old
// actors from the stage and deallocate
void Set_Frame_Head(Augments::Head_Type);
void Set_Frame_Weapon(Augments::Weapon_Type);
void Set_Frame_Body(Augments::Body_Type);
Monster(Augments::Head_Type,
Augments::Weapon_Type,
Augments::Body_Type);
};
};
using PlMonster = Player::Monster;
#endif
monster.cpp
#include "stdafx.h"
#include "Monster.h"
#include "Augments.h"
#include "Angel.h"
void Player::Monster::Refresh(float dt) {
};
int Player::Monster::R_Max_Health() const { return max_health; }
int Player::Monster::R_Curr_Health() const { return curr_health; }
int Player::Monster::R_Attack_Damage() const { return attack_damage; }
Augments::Head* Player::Monster::R_Frame_Head() { return frame_head; }
Augments::Body* Player::Monster::R_Frame_Body() { return frame_body; }
Augments::Weapon* Player::Monster::R_Frame_Weapon() { return frame_weapon; }
void Player::Monster::Set_Max_Health(int x) { max_health = x; }
void Player::Monster::Set_Curr_Health(int x) { curr_health = x; }
void Player::Monster::Add_Curr_Health(int x) { curr_health += x; }
void Player::Monster::Set_Attack_Damage(int x) { attack_damage = x; }
void Player::Monster::Set_Frame_Head(Augments::Head_Type x) {
if ( frame_head != nullptr ) {
frame_head->Destroy();
delete frame_head;
frame_head = nullptr;
}
frame_head = new Augments::Head(x);
theWorld.Add(frame_head);
};
void Player::Monster::Set_Frame_Weapon(Augments::Weapon_Type x) {
if ( frame_weapon != nullptr ) {
theWorld.Remove(frame_weapon);
delete frame_weapon;
frame_weapon = nullptr;
}
frame_weapon = new Augments::Weapon(x);
theWorld.Add(frame_weapon);
};
void Player::Monster::Set_Frame_Body(Augments::Body_Type x) {
if ( frame_body != nullptr ) {
theWorld.Remove(frame_body);
delete frame_body;
frame_body = nullptr;
}
frame_body = new Augments::Body(x);
theWorld.Add(frame_body);
};
Player::Monster::Monster(Augments::Head_Type head,
Augments::Weapon_Type weapon,
Augments::Body_Type body) {
frame_body = nullptr;
frame_head = nullptr;
frame_weapon = nullptr;
Set_Frame_Body(body);
Set_Frame_Head(head);
Set_Frame_Weapon(weapon);
}
source.cpp
#include "stdafx.h"
#include "LD33.h"
#include "Angel.h"
int main ( ) {
Game::Initialize();
theWorld.StartGame();
theWorld.Destroy();
return 0;
}
Errors include things such as:
Error 43 error LNK2005: "public: int __thiscall Player::Monster::R_Attack_Damage(void)const " (?R_Attack_Damage#Monster#Player##QBEHXZ) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\source.obj ClientGame
Error 3 error LNK2005: "public: void __thiscall Player::Monster::Set_Frame_Body(enum Augments::Body_Type)" (?Set_Frame_Body#Monster#Player##QAEXW4Body_Type#Augments###Z) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\LD33.obj ClientGame
And it pretty much states similar for every single function in Monster.
Sorry for just dumping a ton of code. I've been trying to debug it for awhile but couldn't come up with any reasonable solution. I have the include guards, I don't see any namespace conflicts, and everything that needs to be defined is outside of the header files. I can't find anything in augments.h that would be causing this. I also thought it might be the enums, but replacing them with just int did not work either.
I'm thinking it might be the order of the include files? hmm. Maybe there's somehow multiple source files somewhere but I would have no clue as to how. Any help?
Had included Monster.cpp in another header file on accident! Oops
I been writing a program in which, an array will dynamically grow when ever the max size is reach. I have used std::unique_ptr, but I'm not sure what is causing the error. I'm using VS2010.
The error is:
error C2027: use of undefined type 'DyArray::Impl' c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory 2067
Here is the code
DyArray.h
#pragma once
#include <iostream>
#include <memory>
class DyArray
{
public:
DyArray(int IntialSize, int IncrementSize)
{
}
~DyArray()
{
}
void Insert(int Data);
void Set(int Position,int Data);
int Get(int Position);
void Print();
private:
DyArray(const DyArray&);
DyArray& operator=(const DyArray&);
struct Impl;
std::unique_ptr<Impl> m_Impl;
};
DyArray.cpp
#include "LinkedList.h"
#include <iostream>
struct DyArray::Impl
{
typedef struct
{
int* array;
size_t used;
size_t size;
}Array;
public:
Array* m_DyArray;
size_t m_InitalSize;
size_t m_IncrementSize;
Impl(Array* DyArray,int IntialSize,int IncrementSize):m_DyArray(DyArray),m_InitalSize(IntialSize),m_IncrementSize(IncrementSize)
{
m_DyArray->array = (int*)malloc(m_InitalSize * sizeof(int));
m_DyArray->used = 0;
m_DyArray->size = m_InitalSize;
}
~Impl()
{
free(m_DyArray->array);
m_DyArray->array = NULL;
m_DyArray->used = m_DyArray->size = 0;
}
void insertArray(int element)
{
if (m_DyArray->used == m_DyArray->size)
{
m_DyArray->size += m_IncrementSize;
m_DyArray->array = (int*)realloc(m_DyArray->array,m_DyArray->size*sizeof(int));
}
m_DyArray->array[m_DyArray->used++] = element;
}
void Display()
{
std::cout<<"\n";
for (int i = 0; i< m_DyArray->used;i++)
{
std::cout<<m_DyArray->array[i]<<" ";
}
}
};
void DyArray::Insert( int Data )
{
m_Impl->insertArray(Data);
}
void DyArray::Print()
{
m_Impl->Display();
}
Main.cpp
#include "DyArray.h"
#include <iostream>
void main()
{
DyArray dyarray(2,3);
dyarray.Insert(12);
dyarray.Insert(14);
dyarray.Insert(55);
dyarray.Insert(23);
dyarray.Insert(444);
dyarray.Insert(23);
dyarray.Print();
}
The destructor of your class needs to destroy the unique pointer, which in turn needs to delete the Impl it manages. It can only do that if Impl is a complete (i.e. fully defined) type.
Define the destructor in the source file, after the definition of Impl, not in the class definition.
You'll also need to define the constructor there, if you want it to create an Impl and initialise the pointer.
I have a multilevel inheritance (from Ship class -> MedicShip class -> Medic class) with virtual function code as below. I suppose the result should be :
Medic 10
Medic 10
But it generated strange result. On the other hand, if I only use one level inheritance (from Ship class -> Medic class without MedicShip class in between) the result will be OK. Could you find my mistake please? Many thank....
#ifndef FLEET_H
#define FLEET_H
#include <string>
#include <vector>
using namespace std;
class Ship
{
public:
Ship(){};
~Ship(){};
int weight;
string typeName;
int getWeight() const;
virtual string getTypeName() const = 0;
};
class MedicShip: public Ship
{
public:
MedicShip(){};
~MedicShip(){};
string getTypeName() const;
};
class Medic: public MedicShip
{
public:
Medic();
};
class Fleet
{
public:
Fleet(){};
vector<Ship*> ships;
vector<Ship*> shipList() const;
};
#endif // FLEET_H
#include "Fleet.h"
#include <iostream>
using namespace std;
vector<Ship*> Fleet::shipList() const
{
return ships;
}
int Ship::getWeight() const
{
return weight;
}
string Ship::getTypeName() const
{
return typeName;
}
string MedicShip::getTypeName() const
{
return typeName;
}
Medic::Medic()
{
weight = 10;
typeName = "Medic";
}
int main()
{
Fleet fleet;
MedicShip newMedic;
fleet.ships.push_back(&newMedic);
fleet.ships.push_back(&newMedic);
for (int j=0; j< fleet.shipList().size(); ++j)
{
Ship* s = fleet.shipList().at(j);
cout << s->getTypeName() << "\t" << s->getWeight() << endl;
}
cin.get();
return 0;
}
You haven't created any instances of class Medic. Did you mean to say
Medic newMedic;
instead of
MedicShip newMedic;
perhaps? So, the Medic constructor isn't being called and weight and typeName aren't being initialized.
~Ship(){};
The first mistake is right here. This destructor should be virtual if you want to delete derived class objects through base class pointer.