I have a template class that when I instantiate in main doesn't have any issues but when i try instantiating the same in another class is giving issues. can someone please enlighten me on the solution for this
#include<iostream>
#include<string>
using namespace std;
template <class T>
class property {
public:
property(string name)
{
propertyName= name;
}
private:
T item;
string propertyName;
};
main()
{
property<int> myIntProperty("myIntProperty");
}
the above code compiles with out any issue.
but
#include<iostream>
#include<string>
using namespace std;
template <class T>
class property {
public:
property(string name)
{
propertyName= name;
}
private:
T item;
string propertyName;
};
class propertyHolder
{
property<int> myIntProperty("myIntProperty");
};
this code is not getting compiled.
giving me error like
main.cpp|19|error: expected identifier before string constant|
main.cpp|19|error: expected ',' or '...' before string constant|
Thanks,
Harish
property<int> myIntProperty("myIntProperty");
This is a function declaration, so it expects you to insert a default argument after identifying it, like string s = "myIntProperty".
Perhaps you want to initialize an object called myIntProperty,
property<int> myIntProperty {"myIntProperty"};
This can be done in C++11, but you can also initialize it in the constructor initializer list,
// Header
class propertyHolder {
public:
propertyHolder( string s );
private:
property<int> myIntProperty;
};
// Source
propertyHolder::propertyHolder( string s ) :
myIntProperty( s )
{
}
You wanted to declare field in class propertyHandler. That syntax is not working because you cannot declare a field and assing it value at the same spot.
You can delcare it, and initialise in constructor:
property<int> myIntProperty;
propertyHolder(): myIntProperty("name") {}
or with c++11 syntax:
property<int> myIntProperty{"name"};
or declare it static, and them declare like that:
static property<int> myIntProperty;
and after class declaration:
property<int> propertyHolder::myIntProperty("name");
Related
I want to create method with an argument which links to Enemy which is declared later.
Here is my code:
#include <iostream>
#include <vector>
using namespace std;
class Weapon{
public:
int atk_points;
string name;
string description;
void Attack(Entity target){
};
};
class Armor{
public:
int hp_points;
string name;
string description;
int block_chance;
};
class Entity{
public:
int hp;
int atk;
string name;
vector<Weapon> weapons;
vector<Armor> armors;
};
I tried to search for answers, but nothing I found was helpful.
Here's error log:
prog.cpp:9:15: error: ‘Entity’ has not been declared
void Attack(Entity target){
The problem is that the compiler doesn't know what Entity is at the point where you have used as a parameter type. So you need to tell the compiler that Entity is a class type.
There are 2 ways to solve this both of which are given below:
Method 1
To solve this you need to do 2 things given below:
Provide a forward declaration for the class Entity.
Make the parameter of Attack to be a reference type so that we can avoid unnecessary copying the argument and also since we're providing a member function's definition instead of just declaration.
class Entity; //this is the forward declaration
class Weapon{
public:
int atk_points;
string name;
string description;
//------------------------------v------------>target is now an lvalue reference
void Attack(const Entity& target){
};
};
Working demo
Method 2
Another way to solve this is that you can provide just the declaration for the member function Attack' inside the class and then provide the definition after the class Entity's definition as shown below:
class Entity; //forward declaration
class Weapon{
public:
int atk_points;
string name;
string description;
//------------------------------v----------->this time using reference is optional
void Attack(const Entity& target); //this is a declaration
};
//other code here as before
class Entity{
public:
int hp;
int atk;
string name;
vector<Weapon> weapons;
vector<Armor> armors;
};
//implementation after Entity's definition
void Weapon::Attack(const Entity& target)
{
}
Working demo
You can't.
You must declare it earlier. You can, however, define it later, in some circumstances.
To forward declare a class, write this before it is used:
class Entity;
In c++, such code cannot compile:
class A {
void fooa(B) {}
};
class B {
void foob(A) {}
};
However, such code can be compiled, we can change code in the way:
class A { };
class B { };
void fooa(A *, B) {}
void foob(B *, A) {}
It works and nothing is recursive.
So, I don't think change to reference is a good idea. The directly way to do that is just to use some trick. For example, change Entity to auto. Like that: void Attack(auto target).
What's more, with c++20, you can define a concept attackable and make Entity is attackable, I like it much.
I have a templated class:
template <typename vtype>
class BNode
{
public:
BNode::BNode(std::vector<BPoly<vtype>>& thePolys) {if(thePolys.size()) Build(thePolys);}
BNode::BNode() {}
BPlane* mPlane=nullptr;
//And more stuff
};
When I compile, I get this error on the BPlane* mPlane=nullptr line:
error C2146: syntax error: missing ';' before identifier 'BPlane'
(Using Visual Studio 2019 compiler)
Why do I need a semicolon after my {}? If I put the semicolon there, it works. But I'm curious what the problem is because I'm worried there's some issue that will bite me later.
The following code compile without any error:
#include <vector>
class BPlane;
template <class T> class BPoly { int i; };
template <typename vtype>
class BNode
{
public:
BNode(std::vector<BPoly<vtype>> &thePolys) { if (thePolys.size()) Build(thePolys); }
BNode() {}
BPlane *mPlane = nullptr;
void Build(...) {}
//And more stuff
};
int main()
{
BNode<char> s;
}
Thus, it is impossible to guess what you have done wrong as after writing simple types for missing declaration and including vector the code compile without adding any ; after a constructor.
And I have made an instantiation in main to be sure that the class is used.
Quick question: how can I initialize this? The syntax isn't working.
#include <iostream>
using namespace std;
template<typename TYPE>
class Heap1 {
class Node {
public:
friend Heap1;
private:
TYPE elt;
Node *child;
}; // Node
};
int main() {
Heap1<int>.Node var;
return 0; }
I'm reading this answer but the syntax isn't too clear to me: Creating instance of nested class
Heap1<int>.Node var;
The syntax isn't working
Try
Heap1<int>::Node var;
But actually, you can't. Heap1<>::Node is private and thus inaccessible from the outside world.
I'm trying to pass two arguments to a constructor:
class CTest1
{
public:
CTest1(const int i8BitImageID, const int i256BitImageID) : m_i8BitImageID(i8BitImageID), m_i256BitImageID(i256BitImageID) {};
private:
int m_i8BitImageID;
int m_i256BitImageID;
};
#define BITMAP_1_ID 1
#define BITMAP_2_ID 2
class CTest2
{
public:
CTest1 test1(BITMAP_1_ID, BITMAP_2_ID); // Compile error here
};
When I compile this (using Visual Studio 2017), the line where I declare "test1" results in a "C2059: syntax error: 'constant'" error. I've tried with an without "const" in the definition of the constructor.
Thanks!
Default member initializer only works with brace or equals initializer. e.g.
class CTest2
{
public:
CTest1 test1 = CTest1(BITMAP_1_ID, BITMAP_2_ID);
CTest1 test2 {BITMAP_1_ID, BITMAP_2_ID};
};
Or you could use member initializer list.
class CTest2
{
public:
CTest2() : test1(BITMAP_1_ID, BITMAP_2_ID) {}
CTest1 test1;
};
When I try the two forms of constructor in classes of derivation hierarchy, the result turns out to be different. Could anybody tell me why? Below are the test code.
//Person.h
#ifndef PERSON_H_
#define PERSON_H_
#include<string>
using std::string;
class Person{
private:
string firstname;
string lastname;
public:
Person(const char *fn="NoName", const char *ln="NoName"); //A
Person(const string &fn, const string &ln);
virtual ~Person(){}
};
class Gunslinger:virtual public Person{
private:
int notchnum;
public:
Gunslinger(const char*f="unknown",const char*n="unknown",int not=0);//B
virtual ~Gunslinger(){}
};
class PokerPlayer:virtual public Person{
public:
PokerPlayer(const char*fn="unknown", const char*ln="unknown");//C;
virtual ~PokerPlayer(){}
};
class BadDude:public Gunslinger,public PokerPlayer{
public:
BadDude(const char*fn="unknown", const char*ln="unknown", int notc=0);//D
};
#endif
//PersonDefinition.cpp
#include"Person.h"
#include<iostream>
#include<cstdlib>
using std::cout;
using std::endl;
using std::cin;
Person::Person(const char*fn, const char*ln):firstname(fn),lastname(ln){
}
Person::Person(const string &fn,const string &ln):firstname(fn),lastname(ln){
}
Gunslinger::Gunslinger(const char*fn,const char*ln, int not):Person(fn,ln),notchnum(not){
}
PokerPlayer::PokerPlayer(const char*fn,const char*ln):Person(fn,ln){
}
BadDude::BadDude(const char*fn, const char*ln, int notc):Person(fn,ln),PokerPlayer(fn, ln),Gunslinger(fn,ln,notc){
}
//PersonTest.cpp
#include<iostream>
#include "Person.h"
int main(){
Person a("Jack","Husain");
PokerPlayer b("Johnson","William",8);
Gunslinger c("Mensly","Sim");
}
So, here is the problem. The program above fails to compile with the default constructor with default value for all argument and throws an error message saying that "expected ',' or '...' before '!' token", but if I replace the default constructor in Line A,B,C,D with the form without argument, the program compiles and run successfully.Could anyone tell me why? Below is the error message.
You did not implement all the constructors. For instance, you declared a constructor PokerPlayer::PokerPlayer(char*, char*) but you are trying to create a PokerPlayer with PokerPlayer b("Johnson","William",8); (i.e. you never declared a constructor which takes the third argument). The declaration you want for that previous line to work is PokerPlayer::PokerPlayer(char*, char*, int);
Furthermore, you have the exact opposite problem when trying to declare a GunSlinger. Your GunSlinger class requires the third parameter and you are trying to declare it without that argument.
Even though your base class supports several types of constructors, each derived class must also have every constructor you wish to use on it explicitly declared/implemented (with the exception of the default constructor).
EDIT
Here is some semi-functional code:
class PokerPlayer : public Person
{
...
PokerPlayer(char* fname, char* lname, int val);
...
};
Implementation
PokerPlayer::PokerPlayer(char* fname, char* lname, int val) : Person(fname, lname, val)
{
// Anything else we should do...
}