I have a very weird problem... First of all, here are my class's files:
Show.h:
#ifndef SHOW
#define SHOW
#include <iostream>
#include <string>
#include <string.h>
class Show
{
private:
std::string m_time;
int m_serial
public:
Show(const std::string &time, const int &serial);
~Show();
};
#endif
Show.c:
#include "Show.h"
Show::Show(const std::string &time,const int &serial)
{
}
As you can probably see, I only wrote the declaration of the constructor, when the visual studio underlined the second "Show" word in the Show.c file, and told me:
"void Show::Show(const std::string &time,const int &serial)
Show::Show()
Show::Show(const Show &)
Error: no instance of overloaded function "Show::Show" matches the specific type"
And when I stand with the mouse cursor over the constructor function in the Show.h file it looks like that function doesn't exists... I have written some classes in c++ before, and that is the first time anything like that happens to me... help please :(
You forgot to put ; after m_serial field variable. I believe this is the reason of the problem you have. Unfortunately many compilers do not give the exact reason of the problems like this, so you have to be careful with syntax rules.
Related
Overview
I am trying to develop a C++ application which allows for user-created plugins.
I found a nice library called Pluma (http://pluma-framework.sourceforge.net/) which functionally seems to be exactly what I want.
After going through their tutorial, I was able to (with a bit of difficulty) convince the plugin to compile. However, it refuses to play nice and connect with the main program; returning various errors depending on how I try to implement them.
Problem
If I comment out the line labeled 'Main problem line' (in the last file, main.cpp), the plugin compiles successfully, and the main app can recognize it, but it says that "Nothing registered by plugin 'libRNCypher'", and none of the functions can be called.
If I compile that line, the main application instead says "Failed to load library 'Plugins/libRNCypher.so'. OS returned error: 'Plugins/libRNCypher.so: undefined symbol: _ZTIN5pluma8ProviderE".
My guess is that it has something to do with the way the plugin was compiled, as compiling it initially did not work and Code::Blocks told me to compile with "-fPIC" as a flag (doing so made it compile).
Code
Code below:
Main.cpp
#include "Pluma/Pluma.hpp"
#include "CryptoBase.h"
int main()
{
pluma::Pluma manager;
manager.acceptProviderType< CryptoBaseProvider >();
manager.loadFromFolder("Plugins", true);
std::vector<CryptoBaseProvider*> providers;
manager.getProviders(providers);
return 0;
}
CryptoBase.h
#ifndef CRYPTOBASE_H_INCLUDED
#define CRYPTOBASE_H_INCLUDED
#include "Pluma/Pluma.hpp"
#include <string>
#include <vector>
#include <bitset>
//Base class from which all crypto plug-ins will derive
class CryptoBase
{
public:
CryptoBase();
~CryptoBase();
virtual std::string GetCypherName() const = 0;
virtual std::vector<std::string> GetCryptoRecApps() const = 0;
virtual void HandleData(std::vector< std::bitset<8> > _data) const = 0;
};
PLUMA_PROVIDER_HEADER(CryptoBase)
#endif // CRYPTOBASE_H_INCLUDED
RNCypher.h (This is part of the plugin)
#ifndef RNCYPHER_H_INCLUDED
#define RNCYPHER_H_INCLUDED
#include <string>
#include <vector>
#include <bitset>
#include "../Encoder/Pluma/Pluma.hpp"
#include "../Encoder/CryptoBase.h"
class RNCypher : public CryptoBase
{
public:
std::string GetCypherName() const
{
return "RNCypher";
}
std::vector<std::string> GetCryptoRecApps() const
{
std::vector<std::string> vec;
vec.push_back("Storage");
return vec;
}
void HandleData(std::vector< std::bitset<8> > _data) const
{
char letter = 'v';
_data.clear();
_data.push_back(std::bitset<8>(letter));
return;
}
};
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase);
#endif // RNCYPHER_H_INCLUDED
main.cpp (This is part of the plugin)
#include "../Encoder/Pluma/Connector.hpp"
#include "RNCypher.h"
PLUMA_CONNECTOR
bool connect(pluma::Host& host)
{
host.add( new RNCypherProvider() ); //<- Main problem line
return true;
}
Additional Details
I'm compiling on Ubuntu 16.04, using Code::Blocks 16.01.
The second error message seems to not come from Pluma itself, but a file I also had to link, #include <dlfcn.h> (which might be a Linux file?).
I would prefer to use an existing library rather than write my own code as I would like this to be cross-platform. I am, however, open to any suggestions.
Sorry for all of the code, but I believe this is enough to reproduce the error that I am having.
Thank You
Thank you for taking the time to read this, and thank you in advance for your help!
All the best, and happy holidays!
I was not able to reproduce your problem, however looking at
http://pluma-framework.sourceforge.net/documentation/index.htm,
I've noticed that:
in your RNCypher.h file you miss something like
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase)
it seems also that there's no file CryptoBase.cpp containing something like
#include "CryptoBase.h"
PLUMA_PROVIDER_SOURCE(CryptoBase, 1, 1);
finally, in CryptoBase.h I would declare a virtual destructor (see Why should I declare a virtual destructor for an abstract class in C++?) and provide a definition to it, while you should not declare a default constructor without providing a definition to it (see for instance Is it correct to use declaration only for empty private constructors in C++?); of course the last consideration is valid unless there's another file in which you have provided such definitions.
Beginner here - but i was uncertain what exactly to search for this (presumably common) question.
I am working on a program where I have a given class (Dictionary). I am supposed to make a concrete class (Word) which implements Dictionary. I should mention that I am not to change anything in Dictionary.
After making a header file for Word, I define everything in word.cpp.
I am unsure if I am doing this correctly, but I make the constructor read from a given file, and store the information in a public member of Word.
(I understand that the vectors should be private, but I made it public to get to the root of this current issue)
dictionary.h
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
class Dictionary
{
public:
Dictionary(istream&);
virtual int search(string keyword, size_t prefix_length)=0;
};
#endif /* __DICTIONARY_H__ */
word.h
#ifndef __WORD_H__
#define __WORD_H__
#include "dictionary.h"
class Word : public Dictionary{
public:
vector<string> dictionary_words;
vector<string> source_file_words;
Word(istream &file);
int search(string keyword, size_t prefix_length);
void permutation_search(string keyword, string& prefix, ofstream& fout, int& prefix_length);
};
#endif /* __WORD_H__*/
word.cpp
#include "word.h"
Word(istream& file) : Dictionary(istream& file)
{
string temp;
while (file >> temp)
{
getline(file,temp);
dictionary_words.push_back(temp);
}
}
In word.cpp, on the line "Word::Word(istream& file)", I get this error :' [Error] no matching function for call to 'Dictionary::Dictionary()'.
I've been told this is error is due to "Word's constructor invoking Dictionary's ", but I still don't quite grasp the idea well. I am not trying to use Dictionary's constructor, but Word's.
If anyone has an idea for a solution, I would also appreciate any terms related to what is causing this issue that I could look up - I wasn't even sure how to title the problem.
Your child class should invoke parent constructor, because parent object are constructed before child. So you should write something like:
Word::Word(isteam& file) : Dictionary(file)
{
...
}
Seems its better described here What are the rules for calling the superclass constructor?
I'm currently trying to make a game in C++. In my code I'm trying to nest my variables so that my main doesn't have a lot of includes. My problem right now though is that the value of my variables in my class aren't changing. Stepping through the code it shows it setting the value, but it doesn't work. Anyone know what's going on? Thank you in advance.
This is what I have so far:
Location.h
#ifndef LOCATION_H
#define LOCATION_H
#include <string>
class Location
{
public:
Location(void);
Location(std::string name);
~Location(void);
std::string GetName();
void SetName(std::string value);
private:
std::string m_Name
};
#endif
Location.cpp
#include "Location.h"
Location::Location(void): m_Name("") {}
Location::Location(std::string name): m_Name(name) {}
Location::~Location(void)
{
}
std::string Location::GetName()
{return m_Name;}
void Location::SetName(std::string value){m_Name = value;}
PlayerStats.h
#ifndef PLAYERSTATS_H
#define PLAYERSTATS_H
#include "Location.h"
class PlayerStats
{
public:
PlayerStats(void);
~PlayerStats(void);
Location GetLocation();
void SetLocation(Location location);
private:
Location m_Location;
};
#endif
PlayerStats.cpp
#include "PlayerStats.h"
PlayerStats::PlayerStats(void): m_Location(Location()) {}
PlayerStats::~PlayerStats(void)
{
}
Location PlayerStats::GetLocation(){return m_Location;}
void PlayerStats::SetLocation(Location location){m_Location = location;}
main.cpp
#include <iostream>
#include "PlayerStats.h"
using namespace std;
PlayerStats playerStats = PlayerStats();
int main()
{
playerStats.GetLocation().SetName("Test");
cout<< playerStats.GetLocation().GetName()<<endl;
return 0;
}
Your immediate issue is that
Location GetLocation();
returns a copy of the location, so when you call SetName here:
playerStats.GetLocation().SetName("Test");
You're changing the name of the temporary copy, and the change is lost as soon as the semicolon is hit.
More broadly, this kind of design (nesting classes and nesting includes so that main doesn't have a lot of includes, and using a.b.c() style code to access nested members) isn't great C++ style:
Having a bunch of source files that (transitively) include a bunch of header files means that changing a single header file will trigger recompilations of a bunch of source files. Compile times can be a significant issue in larger C++ projects, so reducing compile times by controlling #include's is important. Read up on "forward declarations" for more information.
Writing code like a.b.c() is considered bad object-oriented design, because it reduces encapsulation: not only does the caller have to know about a's details, it has to know about b's also. Sometimes this is the most expedient way to write code, but it's not something to be blindly done just to reduce #include's. Read up on "Law of Demeter" for more information.
If you want to set the result of playerStats.GetLocation(), you could make GetLocation() pass-by-reference (use ampersand, &, on the return argument). Otherwise you are just setting values in a temporary copy of PlayerStats::m_Location.
Alternatively, you could use the SetLocation() function.
I have a class Room and it holds a vector of shared_ptrs to Option objects like so:
private:
vector<shared_ptr<Option> > options;
But for some reason when I build, I get the following errors:
'shared_ptr' : unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
'std::tr1::shared_ptr' : use of class template requires template argument list
Strangely, I also have a vector of shared_ptrs, exact same syntax but there's no problem with that one.
There's also a bunch of places that bring up the error "'Option': undeclared identifier", which brings me to think it might be a problem with the Option class, but it seems to be fine. Here's the code for Option:
Option.h:
#pragma once
#include "Room.h"
#include <memory>
using namespace std;
class Option
{
protected:
int id;
char* text;
public:
Option(void);
Option(int, char*);
virtual ~Option(void);
char* getText();
int getID();
};
Option.cpp:
#include "Option.h"
#include "Room.h"
#include <memory>
using namespace std;
Option::Option(void)
{
}
Option::Option(int newID, char* newText){
id = newID;
text = newText;
}
Option::~Option(void)
{
}
char* Option::getText(){
return text;
}
int Option::getID(){
return id;
}
There is a bit of conjecture in this answer since you haven't posted the code for the Room class. I'm assuming this code
private:
vector<shared_ptr<Option> > options;
is in Room.h. Your Option.h file includes Room.h, hence the Room class gets declared before the Option class. So Option is an incomplete type when the Room class' destructor is compiled and the shared_ptr implementation tries to delete the Option object.
From the code above, I don't see why Option.h needs to include Room.h, in fact, it should be the other way around. If it does indeed need to include the file, you should be able to work around the problem by explicitly declaring Room::~Room() out-of-line in Room.cpp.
EDIT:
Turns out ~shared_ptr<T> does not require T to be a complete type. However, shared_ptr<T>( T* ) and shared_ptr<T>::reset( T* ) do, and the problem may be because some operation on the vector is invoking a call to one of these (more likely the former).
vector<shared_ptr<Option >>
You almost did that right :)
vector<shared_ptr<Option> >
It's the two > characters that, when touching, cause the strange errors you see. It is being interpreted as the >> operator.
BTW, thank you for posting your code exactly as it is rather than typing it back in and possibly hiding the mistake.
I have a constructor for a class that takes in a bool, a pointer to an array, and string.
TheConstructor(bool theBool=true, int *theArray=0, std::string message="0");
Is this the correct way to write it in the header file? My program isn't compiling right now because of a "undefined reference to "the constructor" and to other member functions".
What could be causing this also? I checked and in main.cpp I #included "Class.h" and defined every memberwise function that needed to be defined that was stated in "Class.h" I wrote in "Class.cpp"
I hope you didn't name your class TheConstructor :) If you have class C you can declare its constructor almost as you did - you forgot to put the name of the bool argument:
C.h:
#include <string>
class C
{
public:
C(bool b = 0, int *theArray = 0, std::string message = "0");
};
C.cpp:
#include "C.h"
C::C(bool b, int *theArray, std::string message)
{
}
The first parameter's name is not specified, but that probably wouldn't cause the error you're encountering:
TheConstructor(bool=0, int *theArray=0, std::string message="0");
You probably want to do something like this:
TheConstructor(bool flag=0, int *theArray=0, std::string message="0");
However, without seeing the definition, there is not much else I can say about it. It's difficult to predict what else could be wrong by simply looking at the declaration.