I am new to function pointer and tried to pass the function pointer as parameter from one class to other and getting compiler error.
'fncptr1': is not a class or namespace name"
what am I doing wrong?
fncptr1.h
#ifndef FNCPTR1
#define FNCPTR1
#include "fncptr2.h"
class fncptr1
{
public:
int addition(int a,int b);
void testfncptr();
};
#endif // !FNCPTR1
fncptr1.cpp
#include "fncptr1.h"
#include <iostream>
using namespace std;
int fncptr1::addition(int a,int b)
{
return a + b;
}
void fncptr1::testfncptr()
{
fncptr2 f;
f.implfncptr(&addition);
}
fncptr2.h
#ifndef FNCPTR2
#define FNCPTR2
#include "fncptr1.h"
class fncptr2
{
public:
int implfncptr(int (fncptr1::*add)(int,int));
};
#endif // !FNCPTR2
fncptr2.cpp
#include "stdafx.h"
#include "fncptr2.h"
#include <iostream>
using namespace std;
fncptr1 ff;
int fncptr2::implfncptr(int (fncptr1::*add)(int, int))
{
return (ff.*add)(1,2);
}
main.cpp
fncptr1 f;
f.testfncptr();
Remove the includes of fncptr2.h and fncptr1.h from all .h files. Instead add them to fncptr1.c and fncptr2.c.
you need f.implfncptr(&fncptr1::addition); instead of f.implfncptr(&addition); in fncptr1.cpp
fncptr1.h
#ifndef FNCPTR1
#define FNCPTR1
class fncptr1
{
public:
int addition(int a, int b);
void testfncptr();
};
#endif // !FNCPTR1
fncptr2.h
#ifndef FNCPTR2
#define FNCPTR2
class fncptr1;
class fncptr2
{
public:
int implfncptr(int (fncptr1::* add)(int, int));
};
#endif // !FNCPTR2
fncptr1.cpp
#include "fncptr1.h"
#include "fncptr2.h"
#include <iostream>
using namespace std;
int fncptr1::addition(int a, int b)
{
return a + b;
}
void fncptr1::testfncptr()
{
fncptr2 f;
f.implfncptr(&fncptr1::addition);
}
fncptr2.cpp
#include "fncptr2.h"
#include "fncptr1.h"
#include <iostream>
using namespace std;
fncptr1 ff;
int fncptr2::implfncptr(int (fncptr1::* add)(int, int))
{
return (ff.*add)(1, 2);
}
main.cpp
#include "fncptr1.h"
int main()
{
fncptr1 f;
f.testfncptr();
}
Related
----------------
// fishers.h
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <math.h>
#include <cstring>
namespace tsfresh
{
template<typename T=double>
class FisherTest {
static_assert(std::is_floating_point_v<T>, "FisherTest template T must be float or double");
public:
FisherTest();
T pvalue(int a, int b, int c, int d);
private:
T pValueLog(int a, int b, int c, int d);
};
}
// fishers.cpp
#include "fishers.h"
namespace tsfresh
{
template<typename T>
FisherTest<T>::FisherTest() {
}
template<typename T>
T FisherTest<T>::pvalue(int a, int b, int c, int d) {
return pValueLog(a,b,c,d);
}
template<typename T>
T FisherTest<T>::pValueLog(int a, int b, int c, int d) {
return 0;
}
}
//---
// https://www.codeproject.com/Articles/48575/How-to-Define-a-Template-Class-in-a-h-File-and-Imp
void TempFunc()
{
tsfresh::FisherTest<float> FisherTestFloatObj;
tsfresh::FisherTest<double> FisherTestDoubleObj;
}
// main.cpp
#include <cassert>
#include <iostream>
#include <vector>
#include "fishers.h"
using namespace std;
bool floatEqual(double a, double b) {
return fabs(a-b) <= 1e-6;
}
int main()
{
auto fisher = tsfresh::FisherTest<double>();
int a[] = {1,2,3,4};
cout << fisher.pvalue(a[0], a[1], a[2], a[3]) << "\n";
cout << "All tests passed\n";
return 0;
}
I need to hide implementation details in cpp file, so I need to separate header and source file of my template class. I make 2 instances of the template class that I want to use in the .cpp file (following the solution in the link above), but I still get linking error.
The compile command I use is: g++ -o test main.cpp fishers.cpp -std=c++17
I get the following error: main.cpp:(.text+0x93): undefined reference to tsfresh::FisherTest::pvalue(int, int, int, int)'`
What do I need to change to make this work? I always used header-only template classes, so I don't know what went wrong.
What do I need to change to make this work?
You need to put the implementation of class template FisherTest's member functions inside the header file fishers.h as shown below:
fishers.h
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <math.h>
#include <cstring>
namespace tsfresh
{
template<typename T=double>
class FisherTest {
static_assert(std::is_floating_point_v<T>, "FisherTest template T must be float or double");
public:
FisherTest();
T pvalue(int a, int b, int c, int d);
private:
T pValueLog(int a, int b, int c, int d);
};
//implementation
template<typename T>
FisherTest<T>::FisherTest() {
}
template<typename T>
T FisherTest<T>::pvalue(int a, int b, int c, int d) {
return pValueLog(a,b,c,d);
}
template<typename T>
T FisherTest<T>::pValueLog(int a, int b, int c, int d) {
return 0;
}
}
//declaration for tempfunc
void TempFunc();
fishers.cpp
#include "fishers.h"
void TempFunc()
{
tsfresh::FisherTest<float> FisherTestFloatObj;
tsfresh::FisherTest<double> FisherTestDoubleObj;
}
main.cpp
#include <cassert>
#include <iostream>
#include <vector>
#include "fishers.h"
#include <type_traits>
using namespace std;
bool floatEqual(double a, double b) {
return fabs(a-b) <= 1e-6;
}
int main()
{
auto fisher = tsfresh::FisherTest<double>();
int a[] = {1,2,3,4};
cout << fisher.pvalue(a[0], a[1], a[2], a[3]) << "\n";
cout << "All tests passed\n";
return 0;
}
Demo.
Some of the modifications that i made include:
Moved the implementation of member functions of class template FisherTest to the header fishers.h.
Added a declaration for TempFunc inside header file fishers.h.
The corresponding definition of TempFunc is indside the source file fishers.cpp.
I am new to c++ . The program doesn't compile i am using Xcode. It doesn't give me any error. It just doesn't compile which's weird. Thanks for the help!
I am using 3 files as you can see. I think. there's a problem with the implementation that i can not figure out, if you have any suggestion for a better IDE that Xcode than would be helpful.
Thanks again
Car.cpp
#include <iostream>
#include <string>
#include "Car.h"
using namespace std;
void Car:: setMaker(string m)
{
maker=m;
}
string Car:: getMaker()
{
return maker;
}
void Car:: setModel(int m)
{
model=m;
}
int Car:: getModel()
{
return model;
}
Car.h
#ifndef _CAR_H;
#define _CAR_H;
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Car
{
private:
string maker;
int model;
public:
void setMaker(string m);
string getMaker();
void setModel(int m);
int getModel();
};
#endif
main.cpp
#include <iostream>
#include "Car.cpp"
#include "Car.h"
using namespace std;
int main ()
{
Car c1;
c1.setMaker("BMW");
c1.getMaker();
return 0;
}
I'm trying to learn Inheritance mechanism in C++, I have made a Bancnote(Bills) class, and I want to make a class Card inheriting all the functions and variables from Class Bancnote.
And I get this type of error :
include\Card.h|6|error: expected class-name before '{' token|
BANCNOTE.H
#ifndef BANCNOTE_H
#define BANCNOTE_H
#include <iostream>
#include "Card.h"
using namespace std;
class Bancnote
{
public:
Bancnote();
Bancnote(string, int ,int ,int );
~Bancnote( );
int getsumacash( );
void setsumacash( int );
int getsumaplata( );
void setsumaplata( int );
int getrest( );
void setrest( int );
string getnume( );
void setnume( string );
void ToString();
protected:
private:
string nume;
int sumacash;
int rest;
static int sumaplata;
};
#endif // BANCNOTE_H
BANCNOTE.CPP
#include <iostream>
#include "Bancnote.h"
#include "Card.h"
using namespace std;
int Bancnote::sumaplata=0;
Bancnote::Bancnote(string _nume,int _sumacash,int _rest, int _sumaplata )
{
this->nume=_nume;
this->sumacash=_sumacash;
this->rest=_rest;
this->sumaplata=_sumaplata;
}
Bancnote::Bancnote()
{
this->nume="";
this->sumacash=0;
this->rest=0;
this->sumaplata=0;
}
Bancnote::~Bancnote()
{
cout<<"Obiectul"<<"->" <<this->nume<<"<-"<<"a fost sters cu succes";
}
string Bancnote::getnume()
{
return nume;
}
void Bancnote::setnume(string _nume)
{
this->nume=_nume;
}
int Bancnote::getsumacash()
{
return sumacash;
}
void Bancnote::setsumacash(int _sumacash)
{
this->sumacash=_sumacash;
}
int Bancnote::getsumaplata()
{
return sumaplata;
}
void Bancnote::setsumaplata(int _sumaplata)
{
this->sumaplata=_sumaplata;
}
int Bancnote::getrest()
{
return rest;
}
void Bancnote::setrest(int _rest)
{
this->rest=_rest;
}
void Bancnote::ToString()
{
cout<< "-----"<<getnume()<< "-----"<<endl;
cout<<"Suma Cash: "<<this->getsumacash()<<endl;
cout<<"Suma spre plata: "<<this->getsumaplata()<<endl;
cout<<"Restul:"<<this->getrest()<<endl;
}
CARD.H
#ifndef CARD_H
#define CARD_H
#include "Bancnote.h"
class Card: public Bancnote
{
public:
Card();
virtual ~Card();
protected:
private:
};
#endif // CARD_H
You have messed up the includes. What you have is more or less this:
Bancnote.h:
#ifndef BANCNOTE_H
#define BANCNOTE_H
#include "Card.h" // remove this
struct Bancnote {};
#endif
Card.h
#ifndef CARD_H
#define CARD_H
#include "Bancnote.h"
struct Card : Bancnote {}; // Bancnote is not yet declared
// when compiler reaches here
#endif
When in main you include Bancnote.h then this header includes Card.h so you try to declare Card before Bancnote is declared. Actually Bancnote does not need the definition of Card, so simply removing the include should fix it.
PS: there are other issues (see comments below your question). Most importantly it is not clear why a Card is a Bancnote. Second, never put a using namespace std; inside a header! (see here why)
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)
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;