I was messing around with c++ classes when I ran into an issue. I am trying to make a player class inherit from the Entity class and mix their constructors. The entity class has a constructor that requires you to provide the x position float and the y position float. I want the Player class to require x and y position too, but I also want the name to be required. How would I do this?
Here is my code:
#include <iostream>
class Entity{
public:
float x, y;
int health = 30;
Entity(float X, float Y){
std::cout << "Entity Constructed!" << std::endl;
x = X;
y = Y;
}
~Entity(){
std::cout << "Entity Destructed!" << std::endl;
}
void Print(){
std::cout << x << ", " << y << std::endl;
}
void Move(float mx, float my){
x+=mx;
y+=my;
}
};
class Player : public Entity{
public:
const char* Name;
int attack_damage = 5;
Player(const char* name){
Name = name;
}
void Attack(Entity& entity){
entity.health-=attack_damage;
}
};
int main(){
Entity e(0.0f, 0.0f);
Player p(0.0f,0.0f);
std::cout << e.health << std::endl;
p.Attack(e);
std::cout << e.health << std::endl;
std::cin.get();
}
and here is the error message I got when I tried to compile the code provided above:
FAILED: CMakeFiles/learning-cpp.dir/src/main.cpp.o
/usr/bin/c++ -Wall -Werror -std=c++14 -g -MD -MT CMakeFiles/learning-cpp.dir/src/main.cpp.o -MF CMakeFiles/learning-cpp.dir/src/main.cpp.o.d -o CMakeFiles/learning-cpp.dir/src/main.cpp.o -c src/main.cpp
src/main.cpp: In constructor ‘Player::Player(const char*)’:
src/main.cpp:33:29: error: no matching function for call to ‘Entity::Entity()’
Player(const char* name){
^
src/main.cpp:8:5: note: candidate: ‘Entity::Entity(float, float)’
Entity(float X, float Y){
^~~~~~
src/main.cpp:8:5: note: candidate expects 2 arguments, 0 provided
src/main.cpp:3:7: note: candidate: ‘constexpr Entity::Entity(const Entity&)’
class Entity{
^~~~~~
src/main.cpp:3:7: note: candidate expects 1 argument, 0 provided
src/main.cpp: In function ‘int main()’:
src/main.cpp:44:23: error: no matching function for call to ‘Player::Player(float, float)’
Player p(0.0f,0.0f);
^
src/main.cpp:33:5: note: candidate: ‘Player::Player(const char*)’
Player(const char* name){
^~~~~~
src/main.cpp:33:5: note: candidate expects 1 argument, 2 provided
src/main.cpp:28:7: note: candidate: ‘constexpr Player::Player(const Player&)’
class Player : public Entity{
^~~~~~
src/main.cpp:28:7: note: candidate expects 1 argument, 2 provided
src/main.cpp:28:7: note: candidate: ‘constexpr Player::Player(Player&&)’
src/main.cpp:28:7: note: candidate expects 1 argument, 2 provided
ninja: build stopped: subcommand failed.
Try this
Player(float x, float y, const char* name)
: Entity(x,y)
{
Name = name;
}
Related
Here's the Code:
#include<iostream>
#include<string>
#include<vector>
enum class OrderBookType{bid, ask};
class OrderBookEntry{
public:
OrderBookEntry( double _price,
double _amount,
std::string _timeStamp,
std::string _product,
OrderBookType _orderType)
{
price = _price;
amount= _amount;
timeStamp= _timeStamp;
product= _product;
orderType= _orderType;
}
double price;
double amount;
std::string timeStamp;
std::string product;
OrderBookType orderType;
};
int main(){
OrderBookEntry order1{102000.01, 0.0001, "2020/03/17 17:01:24.884492", "ETH/BTC", OrderBookType::bid};
std::cout << "price: " << std::fixed << order1.price << std::endl;
return 0;
}
The error I'am getting:
main.cpp:5:6: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions]
enum class OrderBookType{bid, ask};
^
main.cpp:33:20: error: no matching constructor for initialization of 'OrderBookEntry'
OrderBookEntry order1{102000.01, 0.0001, "2020/03/17 17:01:24.884492", "ETH/BTC", OrderBookType::bid};
^
main.cpp:7:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class OrderBookEntry{
^
main.cpp:10:9: note: candidate constructor not viable: requires 5 arguments, but 0 were provided
OrderBookEntry( double _price,
^
main.cpp:33:26: error: expected ';' at end of declaration
OrderBookEntry order1{102000.01, 0.0001, "2020/03/17 17:01:24.884492", "ETH/BTC", OrderBookType::bid};
^
;
1 warning and 2 errors generated.
As the compiler error indicates, enum class are supported only from C++ 11 onwards, so when you compile, you must pass a flag/switch or param to your c++ compiler to use that version of the language syntax, then only it will compile your OrderBookType::bid last argument passed in the constructor.
header file:
#ifndef CONTMEM_H
#define CONTMEM_H
class Contmem {
public:
Contmem(int a, int b, int c);
int total;
int mem;
const int constmem;
int printconst() const;
const int constant;
void print();
};
#endif // CONTMEM_H
Contmem.cpp file:
#include "Contmem.h"
#include <iostream>
Contmem::Contmem(int a, int b, int c)
: mem(a), constmem(b), constant(c)
{
total = mem * constmem * constant;
}
void Contmem::print()
{
std::cout << "This is my variable member " << mem << " and this is my constmem member " << constmem << "with the constant member" << constant << std::endl;
}
int Contmem::printconst() const
{
return total;
std::cout << "This is the total variable " << total << std::endl;
}
main function :
#include <iostream>
#include "Contmem.h"
int main()
{
Contmem cont(3, 4, 5);
cont.print();
const Contmem obj;
obj.printconst();
}
error file:
|=== Build: Debug in CONST_&_MEMBER_INITIALIZER
(compiler: GNU GCC Compiler) ===| C:\C++
CODEBLOCK\CONST_&_MEMBER_INITIALIZER\main.cpp||
In function 'int main()':| C:\C++
CODEBLOCK\CONST_&_MEMBER_INITIALIZER\main.cpp|9|error:
no matching function for call to 'Contmem::Contmem()'|
C:\C++ CODEBLOCK\CONST_&_MEMBER_INITIALIZER\Contmem.h|8|note: candidate:
Contmem::Contmem(int, int, int)| C:\C++
CODEBLOCK\CONST_&_MEMBER_INITIALIZER\Contmem.h|8|note: candidate
expects 3 arguments, 0 provided| C:\C++
CODEBLOCK\CONST_&_MEMBER_INITIALIZER\Contmem.h|5|note: candidate:
Contmem::Contmem(const Contmem&)| C:\C++
CODEBLOCK\CONST_&_MEMBER_INITIALIZER\Contmem.h|5|note: candidate
expects 1 argument, 0 provided| ||=== Build failed: 1 error(s), 0
warning(s) (0 minute(s), 0 second(s)) ===|
You're missing a default constructor for your class. You only have this one
Contmem::Contmem(int a, int b, int c)
: mem(a), constmem(b), constant(c)
{
total = mem * constmem * constant;
}
but here
int main()
{
Contmem cont(3, 4, 5);
cont.print();
const Contmem obj; // <--here
obj.printconst();
}
you are trying to construct a new Contmem object without passing those 3 arguments
Actually, those compiler errors are telling you what the real problem is.
const Contmem obj;
attempts to call the default constructor, Contmem().
BUT because of:
Contmem::Contmem(int a, int b, int c)
: mem(a), constmem(b), constant(c)
which has a mem-initializer and a const member, your default constructor is deleted.
Thus, compiler can't match that statement to any of the existing constructor, since only your mem-initializer constructor exists.
Why are the function calls to waitForEvent in main below ambiguous?
#include <iostream>
struct Event1 { char c1[1]; };
struct Event2 { char c2[2]; };
template<class Event> struct EventSource
{
void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
};
typedef EventSource<Event1> Event1Source;
typedef EventSource<Event2> Event2Source;
struct Event12Source : public Event1Source, public Event2Source {};
int main()
{
Event12Source source;
source.waitForEvent(Event1());
source.waitForEvent(Event2());
return 0;
}
Compiling it I get the following errors:
user#AHERLADUSERVM2:~/test/TemplateMultipleMethodInheritance$ g++ test.cpp test.cpp: In function ‘int main()’: test.cpp:19:12: error: request for member ‘waitForEvent’ is ambiguous
source.waitForEvent(Event1());
^ test.cpp:7:10: note: candidates are: void EventSource<Event>::waitForEvent(Event) [with Event = Event2]
void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
^ test.cpp:7:10: note: void EventSource<Event>::waitForEvent(Event) [with Event = Event1] test.cpp:20:12: error: request for member ‘waitForEvent’ is ambiguous
source.waitForEvent(Event2());
^ test.cpp:7:10: note: candidates are: void EventSource<Event>::waitForEvent(Event) [with Event = Event2]
void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
^ test.cpp:7:10: note: void EventSource<Event>::waitForEvent(Event) [with Event = Event1]
(Why) is this not a simple case of function overloading resolution?
Thanks,
Damian
This may not be what you want, but it will solve the ambiguity
source.EventSource<Event1>::waitForEvent(Event1());
source.EventSource<Event2>::waitForEvent(Event2());
Also, if you are ever tempted to add a base class to Event1 and Event2, be aware of this
Because overloading does not work with inheritance. The derived class inherited the same function from two base classes which ambiguous.
I have this piece of code that compiles fine with clang (even with -Weverything), but for which gcc issues an error.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
class PhonebookWriter
{
public:
PhonebookWriter(const string& fname):
fname_(fname), names_(), numbers_() {}
PhonebookWriter& operator()(const string& name,
const string& number)
{
names_.push_back(name);
numbers_.push_back(number);
return *this;
}
~PhonebookWriter(void)
{
ofstream f(fname_.c_str());
for(size_t i=0;i<names_.size();++i)
f << names_[i] << " " << numbers_[i] << "\n";
f.close();
}
private:
const string fname_;
vector<string> names_;
vector<string> numbers_;
};
namespace {
void write_guests_data(const string& fname)
{
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
}
}
int main(void)
{
write_guests_data("phone_book.txt");
return 0;
}
and here's what I get when I try to compile the code:
$ g++ ./test.cpp
./test.cpp: In function ‘void {anonymous}::write_guests_data(const string&)’:
./test.cpp:39:27: error: declaration of ‘PhonebookWriter fname’ shadows a parameter
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
./test.cpp:39:48: error: no matching function for call to ‘PhonebookWriter::PhonebookWriter(const char [11], const char [6])’
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
./test.cpp:39:48: note: candidates are:
./test.cpp:11:3: note: PhonebookWriter::PhonebookWriter(const string&)
PhonebookWriter(const string& fname):
^
./test.cpp:11:3: note: candidate expects 1 argument, 2 provided
./test.cpp:7:7: note: PhonebookWriter::PhonebookWriter(const PhonebookWriter&)
class PhonebookWriter
^
./test.cpp:7:7: note: candidate expects 1 argument, 2 provided
./test.cpp:39:49: error: expected ‘,’ or ‘;’ before ‘(’ token
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
My gcc version is 4.9.1, and my clang version is 3.5.0.
I don't understand why there should even be a shadowing problem. Even if there were, it should have been picked up by clang.
Change:
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
to:
(PhonebookWriter(fname))("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
EXPLANATION
For some reason gcc removes the braces around fname, which turns the line into:
PhonebookWriter fname ("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
And now the errors make sense.
I tried to implement Properties in c++. I don't no why but if I want to compile my code there are quite a lot of errors. The main Idea was, that a template class and the tamplate constructor will give the requirement Informations.
I would be grateful if somebody could help me!
Compiling Message:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o PropertyTest2 PropertyTest2.cpp
PropertyTest2.cpp:22:16: error: expected ‘;’ at end of member declaration
PropertyTest2.cpp:22:19: error: expected unqualified-id before ‘<’ token
PropertyTest2.cpp: In function ‘int main()’:
PropertyTest2.cpp:34:20: error: use of deleted function ‘PropertyTestClass::PropertyTestClass()’
PropertyTest2.cpp:8:7: error: ‘PropertyTestClass::PropertyTestClass()’ is implicitly deleted because the default definition would be ill-formed:
PropertyTest2.cpp:8:7: error: no matching function for call to ‘Property<int>::Property()’
PropertyTest2.cpp:8:7: note: candidates are:
Property4.cpp:21:2: note: template<int (** G)(), void (** S)(int&)> Property::Property()
Property4.cpp:6:7: note: constexpr Property<int>::Property(const Property<int>&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
Property4.cpp:6:7: note: constexpr Property<int>::Property(Property<int>&&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
PropertyTest2.cpp:38:20: error: no matching function for call to ‘Property<int>::Set(int)’
PropertyTest2.cpp:38:20: note: candidate is:
Property4.cpp:30:7: note: void Property<T>::Set(T&) [with T = int]
Property4.cpp:30:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’
Property Class (Property.cpp)
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
template <class T>
class Property {
private:
typedef T (*TGetter)(void);
typedef void (*TSetter)(T &);
TGetter Getter;
TSetter Setter;
public:
typedef T type;
template<TGetter *G,
TSetter *S
>
Property() {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(T &value) {
(this->Setter)(value);
}
};
#endif
Testing file (PropertyTest.cpp):
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter(void) {
return this->_age;
}
void AgeSetter(int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age<&PropertyTestClass::AgeGetter, &PropertyTestClass::AgeSetter>;
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Ok, this time fixed all the problems in your code.
Property.cpp:
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
#include <boost/function.hpp>
template <class T>
class Property {
private:
typedef boost::function <T()> TGetter;
typedef boost::function <void(const T&)> TSetter;
TGetter Getter;
TSetter Setter;
public:
typedef T type;
Property(TGetter G, TSetter S) {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(const T &value) {
(this->Setter)(value);
}
};
#endif
PropertyTests.cpp:
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include <boost/bind.hpp>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter() {
return this->_age;
}
void AgeSetter(const int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age;
PropertyTestClass() : age(
boost::bind(&PropertyTestClass::AgeGetter, this),
boost::bind(&PropertyTestClass::AgeSetter, this, _1))
{}
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Output:
$ ./a.out
Property Test Programm
ReadWrite Property for age
5