I have simple class in a header file: a.hh
#ifndef a_hh
#define a_hh
class a
{
public:
int i;
a()
{
i = 0;
}
};
#endif
Then i have a file:b.cc
#include <iostream>
#include "a.hh"
using namespace std;
int main(int argc, char** argv)
{
a obj;
obj.i = 10;
cout << obj.i << endl;
return 0;
}
>
Till this point everything is fine.
I compile the code and it compiles fine.
But as soon as i add a vector in the class:
#ifndef a_hh
#define a_hh
class a
{
public:
int i;
vector < int > x;
a()
{
i = 0;
}
};
#endif
I get a compilation error as below:
> CC b.cc
"a.hh", line 7: Error: A class template name was expected instead of vector.
1 Error(s) detected.
What is the problem with declaring a vector here as a member?
You need to #include <vector> and use the qualified name std::vector<int> x;:
#ifndef a_hh
#define a_hh
#include <vector>
class a{
public:
int i;
std::vector<int> x;
a() // or using initializer list: a() : i(0) {}
{
i=0;
}
};
#endif
Other points:
(as commented by EitanT) I removed the additional qualification a:: on the constructor
have a read of Why is "using namespace std" considered bad practice?
declaring a vector as a class member:
#include <iostream>
#include <vector>
using namespace std;
class class_object
{
public:
class_object() : vector_class_member() {};
void class_object::add_element(int a)
{
vector_class_member.push_back(a);
}
void class_object::get_element()
{
for(int x=0; x<vector_class_member.size(); x++)
{
cout<<vector_class_member[x]<<" \n";
};
cout<<" \n";
}
private:
vector<int> vector_class_member;
vector<int>::iterator Iter;
};
int main()
{
class_object class_object_instance;
class_object_instance.add_element(3);
class_object_instance.add_element(6);
class_object_instance.add_element(9);
class_object_instance.get_element();
return 0;
}
1.You need to #include <vector> and using namespace std, then a.hh just like below:
#ifndef a_hh
#define a_hh
#include <vector>
using namespace std;
class a
{
public:
int i;
vector <int> x;
a()
{
i = 0;
}
};
#endif
2. If you don't want to only use std namespace in all your code, you can specified the namespace before type, just like std::vector<int> x;
Related
I have following C++ code
A.h
namespace x {
namespace y {
namespace z {
struct Container;
class A
{
public:
A(Container& _container);
void info();
private:
Container& container;
};
}
}
}
A.cpp
#include "A.h"
#include <iostream>
namespace x {
namespace y {
namespace z {
A::A(Container& _container) : container(_container) {}
void A::info() {
std::cout << "Instance of A!" << std::endl;
}
}
}
}
Container.h
#include "A.h"
namespace x {
namespace y {
namespace z {
struct Container {
Container(): a(*this) {}
A a;
};
}
}
}
main.cpp
#include <cstdlib>
#include "Container.h"
int main(int argc, char** argv) {
x::y::z::Container container;
container.a.info();
return 0;
}
The above mentioned code is compilable and workable.
But let's say I move the Container.h out of the z namespace and let it in the y namespace (nested in the x namespace). So the code will look like that
A.h
namespace x {
namespace y {
namespace z {
struct Container;
class A
{
public:
A(x::y::Container& _container);
void info();
private:
x::y::Container& container;
};
}
}
}
A.cpp
#include "A.h"
#include <iostream>
namespace x {
namespace y {
namespace z {
A::A(x::y::Container& _container) : container(_container) {}
void A::info() {
std::cout << "Instance of A!" << std::endl;
}
}
}
}
Container.h
#include "A.h"
namespace x {
namespace y {
struct Container {
Container(): a(*this) {}
x::y::z::A a;
};
}
}
main.cpp
#include <cstdlib>
#include "Container.h"
int main(int argc, char** argv) {
x::y::Container container;
container.a.info();
return 0;
}
In that case the compilation fails with following error messages:
In file included from A.cpp:7:
A.h:26:22: error: expected ')' before '&' token
26 | A(x::y::Container& _container);
| ~ ^
| )
A.h:31:11: error: 'Container' in namespace 'x::y' does not name a type
31 | x::y::Container& container;
| ^~~~~~~~~
A.cpp:14:5: error: expected constructor, destructor, or type conversion before '(' token
14 | A::A(x::y::Container& _container) : container(_container)
| ^
Can anybody tell me why these error messages pop up in case I move the Container.h from the z namespace and let it in the y namespace nested in the x namespace?
The problem is that you never declared x::y::Container in A.h. You did declare x::y::z::Container, but that doesn't name the same type. Simply move the declaration into the y namespace:
namespace y {
namespace z {
struct Container;
Into ->
namespace y {
struct Container;
namespace z {
My question is that, I have a template class template<class T> AList as base, and I wanna get a derived class from the template, i.e. get class BList: public AList<mydefinedtype> without much modification.
alist.h
#ifndef alist_h
#define alist_h
template<class T> class AList
{
public:
AList(){
arr = new T[20];
numitems = 0;
};
void append(T value);
private:
T *arr;
int numitems;
};
#endif /* alist_h */
alist.cpp
#include "alist.h"
template<class T> void AList<T>::append(T value)
{
arr[numitems] = value;
++numitems;
return;
}
blist.h
#include "alist.cpp"
#include <string>
using namespace std;
typedef struct
{
string a, b;
int key;
} record;
class BList: public AList<record>{
public:
void test(void){
cout << "this is from BList" << endl;
}
};
blist.cpp
#include "blist.h"
main.cpp
#include <iostream>
#include "blist.cpp"
using namespace std;
int main(){
record testRecord[3];
testRecord[0] = {"Mark", "A", 1};
testRecord[1] = {"Anla", "B", 2};
testRecord[2] = {"Cindy", "C", 3};
BList blist = BList();
for(auto i: testRecord){
// blist.append(i); // will compile error
blist.test();
}
return 0;
}
It will fail as follows, I wonder how to compile or how to fix the bug.
error info
Undefined symbols for architecture x86_64:
"AList<record>::append(s)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
Not sure where comes from the issue.
// Example program
#include <iostream>
#include <string>
struct record{
int a;
};
template<class T>
class AList{
public:
AList()=default;
void append(T value){}
};
template<class T>
class BList:public AList<T>{
public:
void test(void){}
};
int main()
{
BList<record> blist;
record recordarr[3] ;
// some initialization
for(auto i:recordarr){
blist.append(i);
blist.test();
}
}
The problem you have is that the AList() constructor, append(T) and test() are only declared but not defined. The above code should compile.
You should put your template classes entirely in header files. See this question and this C++ FAQ for details on why.
You should also never #include .cpp files. You should only ever #include header files.
Below I have your code after the required modifications to make it compile. I also removed your memory leak.
alist.h:
#ifndef alist_h
#define alist_h
template<class T> class AList {
public:
AList() {
arr = new T[20];
numitems = 0;
};
~AList() {
delete[] arr;
}
void append(T value) {
arr[numitems] = value;
++numitems;
}
private:
T *arr;
int numitems;
};
#endif /* alist_h */
blist.h:
#ifndef blist_h
#define blist_h
#include "alist.h"
#include <string>
using namespace std;
typedef struct {
string a, b;
int key;
} record;
class BList: public AList<record> {
public:
void test(void) {
cout << "this is from BList" << endl;
}
};
#endif /* blist_h */
main.cpp:
#include <iostream>
#include "blist.h"
using namespace std;
int main() {
record testRecord[3];
testRecord[0] = {"Mark", "A", 1};
testRecord[1] = {"Anla", "B", 2};
testRecord[2] = {"Cindy", "C", 3};
BList blist = BList();
for (auto i: testRecord) {
blist.append(i);
blist.test();
}
return 0;
}
Summary of changes
I made the following changes:
Moved body of AList::append into alist.h, and deleted alist.cpp
Added AList destructor to free the dynamically allocated memory allocated in AList::AList
In blist.h, included alist.h instead of alist.cpp
Deleted blist.cpp
In main.cpp, included blist.h instead of blist.cpp
This question already has answers here:
Initialize base class with no default constructor in constructor of derived class
(3 answers)
Closed 3 years ago.
I'm learning oop in c++ and have the following error:
In constructor 'pflFr1::pflFr1()'
Error: No matching function for call to worldBuilder::worldBuilder()
The class worldbuilder is generating protected 2d arrays. The class pflfr1 is inherting from worldbuilder. But somehow, the constructor of worldbuilder has a problem.
My code:
main.cpp:
#include <iostream>
#include "pflfr1.h"
#include "worldbuilder.h"
#include <vector>
using namespace std;
int main()
{
srand(time(0));
int sl = 10;
worldBuilder w_obj(sl);
w_obj.buildPhyWelt();
w_obj.buildVegWelt();
pflFr1 objekt();
return 0;
}
worldbuilder.h:
#ifndef WORLDBUILDER_H
#define WORLDBUILDER_H
#include <vector>
using namespace std;
class worldBuilder
{
public:
worldBuilder(int sl_);
vector<vector<int> > buildPhyWelt();
vector<vector<int> > buildVegWelt();
protected:
vector<vector<int> > phyWelt;
vector<vector<int> > vegWelt;
int sl;
private:
};
#endif // WORLDBUILDER_H
worldbuilder.cpp:
#include <iostream>
#include "worldbuilder.h"
#include <vector>
using namespace std;
worldBuilder::worldBuilder(int sl_)
: sl(sl_)
{
}
vector<vector<int> > worldBuilder::buildPhyWelt()
{
phyWelt.resize(sl, vector<int>(sl));
// initialisiere physische Welt
// 1 = land, -1 ist meer
for(int i=0; i<sl; i++)
{
for(int j=0; j<sl; j++)
{
phyWelt[i][j] = 1;
}
}
}
vector<vector<int> > worldBuilder::buildVegWelt()
{
vegWelt.resize(sl, vector<int>(sl));
// initialisiere Nahrung
for(int i=0; i<sl; i++)
{
for(int j=0; j<sl; j++)
{
if(rand()%100<=2)
{
vegWelt[i][j] = 1;
}
else
{
vegWelt[i][j] = 0;
}
}
}
}
pflfr1.h:
#ifndef PFLFR1_H
#define PFLFR1_H
#include <vector>
#include "worldbuilder.h"
using namespace std;
class pflFr1: protected worldBuilder
{
public:
pflFr1();
protected:
private:
int y;
int x;
int hp;
};
#endif // PFLFR1_H
pflfr1.cpp:
#include <iostream>
#include <pflfr1.h>
#include <cstdlib>
#include <ctime>
using namespace std;
pflFr1::pflFr1()
: hp(10)
{
int initPosY = rand()%sl;
int initPosX = rand()%sl;
y = initPosY;
x = initPosX;
}
Your default constructor pflFr1::pflFr1() 's implementation is rewritten as
pflFr1::pflFr1()
: worldBuilder(), hp(10){
...
}
Because the pflFr1 class derives from worldBuilder, its constructor must be called as part of pflFr1 object creation. The default behaviour is to call the default constructor of the base - worldBuilder().
But this constructor does not exist. You only declared worldBuilder::worldBuilder(int sl_);. By doing so you disabled the automatic generation of default constructors for classes, which is done only if no user-defined constructor was declared.
Either you can write worldBuilder()=default; inside the class, which will leave s1 uninitialized. Or you can use delegating constructors - worldBuilder():worldBuilder(0){}.
I want to pass my vector "myStaffs" from Team Class by reference to Manage Class because I want to manipulate the data of staffs and sort them. How do I pass it by reference?
Header Staff
#ifndef STAFF_H
#define STAFF_H
#include <vector>
#include <cstdlib>
#include <ctime>
#include <string>
class Staff
{
public:
Staff();
Staff(int, int, int, int);
~Staff();
static int genRanNum(int);
static Staff* createStaff(int);
const int getSize();
private:
int staSkills1,staSkills2,staSkills3;
int staId;
//int staDeptAsigned;
//std::string staName;
};
#endif
CPP Staff
#include "Staff.h"
#include <iostream>
using namespace std;
Staff::Staff():
staId(0),
staSkills1(0),
staSkills2(0),
staSkills3(0)
{
}
Staff::Staff(int id, int s1, int s2, int s3):
staId(id),
staSkills1(s1),
staSkills2(s2),
staSkills3(s3)
{
}
Staff *Staff::createStaff(int s)
{
Staff *staff = new Staff();
staff->staId = s;
staff->staSkills1 = genRanNum(10);
staff->staSkills2 = genRanNum(10);
staff->staSkills3 = genRanNum(10);
return staff;
}
int Staff::genRanNum(int num)
{
return 1+(rand()%num);
}
Staff::~Staff()
{
}
Header Team
#ifndef TEAM_H
#define TEAM_H
#include "Staff.h"
#include <vector>
#include <iostream>
using std::vector;
class Team: public Staff
{
public:
Team();
~Team();
private:
vector<Staff *> myStaffs;
};
#endif // TEAM_H
CPP Team
#include "Team.h"
const int SIZE = 30;
Team::Team():
myStaffs(SIZE)
{
for(int iStaff = 0; iStaff <= SIZE; iStaff++)
{
myStaffs[iStaff] = createStaff(iStaff);
}
}
Team::~Team()
{
}
Header Manage
#ifndef OPTIONS_H
#define OPTIONS_H
#include "Team.h"
#include <vector>
#include <iostream>
using std::vector;
class Manage
{
public:
Manage();
~Manage();
private:
// vector
};
CPP Manage
#include "Manage.h"
Manage::Manage()
{
}
Manage::~Manage()
{
}
#endif
Its simple you pass it as you would pass any other object by reference
int sortEmployee(std::vect<Staff *> &staffList> {
// ... code to sort Employee
}
and you can call it like below
vector<Staff *> myStaffs
result = sortEmployee(myStaffs);
It's as simple as
#include <vector>
void myVectorManglingFun(std::vector<Staff *> &myStaff) //notice the &
{
//do something here
}
If you don't need to modify the vector, then always use a const reference.
void myVectorReadingFun(const std::vector<Staff *> &myStaff)
How do I execute a member's function by passing the object and the member's function to another function in c++. I do understand the answer to my question is out there; however, I do not know what this is called. So far I created 2 files, exeFunc.h and exeFunc.cpp. Their code consist of:
exeFunc.h
/*
File: exeFunc.h
Header file for exeFunc Library.
*/
#ifndef EXEFUNC_H
#define EXEFUNC_H
#include "mbed.h"
#include "msExtensions.h"
#include "cfExtensions.h"
#include <map>
class exeFunc
{
public:
exeFunc(msExtensions &msExt, cfExtensions &cfExt);
private:
void _splitFuncFromCmd();
void _attachCallback();
msExtensions &_msExt;
cfExtensions &_cfExt;
//FunctionPointer _p;
};
#endif
exeFunc.cpp
/*
File: exeFunc.cpp
Execute functions in other Sensor libraries/classes
Constructor
*/
#include "mbed.h"
#include "ConfigFile.h"
#include "msExtensions.h"
#include "cfExtensions.h"
#include "exeFunc.h"
#include <map>
#include <string>
using namespace std;
exeFunc::exeFunc(msExtensions &msExt, cfExtensions &cfExt) : _msExt(msExt), _cfExt(cfExt)
{
//_cfExt.checkConfigForFirstStart();
//_p.attach(&_cfExt, &cfExtensions::checkConfigForFirstStart);
//_p.call();
}
void exeFunc::_splitFuncFromCmd()
{
}
void exeFunc::_attachCallback()
{
}
I wrote a completed example, may helps
class MyClass
{
public:
MyClass(int b)
:_b(b)
{
}
int Foo(int a)
{
return a * _b;
}
int _b;
};
typedef int (MyClass::*MFP)(int);
int get_result(MyClass* obj, MFP mfp)
{
int r = (obj->*mfp)(5); // 30
return r;
}
int _tmain(int argc, _TCHAR* argv[])
{
MFP mfp = &MyClass::Foo;
MyClass m(6);
get_result(&m, mfp);
return 0;
}
You call it by another function.if you have an independent function.
To be honesty your question is not completely clear.However :
int F(int,int,int);
int g();
//main scope
F(g(),a,b)