Trouble instantiating class with reference to another class - c++

I'm trying to instantiate a few classes, with references to the first class passed along.
The compiler gives me an error stating: error: 'classData' is not a type.
ClassData hold some complicated data structures and has a bunch of accessors to that data. ClassFunc has a bunch of functions that operate on that data. Then the Work class does a bunch of work and occasionally needs to call a function in ClassB that will do some work on the data in ClassData.
Below is the code:
/////////////////////////
//ClassData.h
class ClassData {
public:
ClassData(){
// initialize a bunch of stuff
};
virtual ~ClassData(){};
}
/////////////////////////
//ClassFunc.h
#include "ClassData.h"
class ClassFunc {
public:
ClassFunc(ClassData& in_classData) : classData(in_classData){};
virtual ~ClassFunc();
float updateEta(float deltaVJ, int column);
private:
ClassData& classData;
};
/////////////////////////
//ClassFunc.cpp
#include "ClassFunc.h"
float ClassFunc::updateEta(float a, int b){
float foo = 0.0
// Do a bunch of work to foo
return foo;
};
/////////////////////////
// Work.h
#include "ClassData.h"
#include "ClassFunc.h"
class Work{
public:
Work(ClassData& in_class) : classData(in_class){
// initialize some stuff
};
~Work(){};
float updateTheta(int a, float b, float c);
private:
ClassData& classData;
ClassFunc classFunc(classData); //// ERROR IS HERE
}
/////////////////////////
// Work.cpp
#include "Work.h"
float Work::updateTheta(int a, float b, float c){
// do some work first
double foo = classFunc.updateEta(d, e);
return foo
};

Your compiler's right: classA isn't a type. C++ is case-sensitive; ClassA is the type you're looking for (check the first line of ClassB's constructor).
Hope that helps!

Answer After question modification
ClassFunc classFunc(classData); is not valid syntax in the definition of a class. You will need to have this classFunc variable by either a set function or through the constructor.
However, writing just a setter will be difficult because your ClassFunc requires a ClassData. In order to work around this, you may need to modify your ClassFunc also.
Also, there is another error. ClassData and Work are missing a ; at the end of its definition.
Original Answer before question modification
There are several errors in this code. Such as
float ClassA::funcA{
Should be
float ClassA::funcA(){
As other wise, it looks like a function definition.
Second, there is
ClassB(Class A& in_classA): classA(in_classA){
As it should be
ClassB(ClassA& in_classA): classA(in_classA){
As Class A is not a type.
Also, you are missing several semicolons but those should be obvious to spot.

The problem is that you cannot initialize member variables in the class declaration:
ClassFunc classFunc(classData);
Instead, initialize it in the initializer list of the constructor:
Work(ClassData& in_class) : classData(in_class), classFunc(classData) {}

Related

Initialising a vector of structs containing function pointers gives "no viable overloaded '=' "

I am trying to write a chip CPU emulator and implementing its instruction table as a vector of structs where each struct contains a value and a function pointer to a particular operation. My compiler (clang++) however gives me the error:
no operator "=" matches these operands -- operand types are: std::__1::vector<A::someStruct, std::__1::allocator<A::someStruct>> = {...}
and:
no viable overloaded '='
for the line func_table = {{1,&A::func1},{2,&A::func2}};
I'm using the exact same syntax used in a similar project on GitHub but I still get these errors. It only seems to be a problem initialising with structs of non-null function pointers. I'm very new to programming with C++ so i'd love to know what I'm misunderstanding. Below is an example of the header and source file
#include <vector>
class A{
public:
A();
private:
struct someStruct{
int a = 0;
void (*fptr)(void) = nullptr;
};
std::vector<someStruct> func_table;
void func1();
void func2();
};
#include "tutorial.h"
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}}; // two entries here, but the table is 512 long
}
void A::func1(){
// something
}
void A::func2(){
// something else
}
int main(){
A example;
return 0;
}
I don't understand what these errors mean and why brace initialisation seems to have a problem with function pointers. I would really appreciate any input on this. Thanks
The structure definition should look like
struct someStruct{
int a = 0;
void (A::*fptr)(void) = nullptr;
};
because you are trying to use member functions of the class A as initializers.
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}};
}
That is you have to declare pointers to class members.

How do I write a proper class definition & declaration when a member is a user defined class?

I have a class defined in a header file:
class TempLogger {
private:
int pin;
OneWire thermo;
public:
TempLogger(int);
float read();
};
And a cpp file with:
TempLogger::TempLogger(int x) {
pin = x;
OneWire thermo(pin);
}
My compiler claims "no matching function for call to 'OneWire::OneWire()' pointing at the first line of the CPP file. What am I doing wrong and why?
It looks like OneWire doesn't have non-parametric constructor, which is tried to be called at TempLogger initialization step. You can either write a non-parametric constructor or even better call the parametric one in initialization list:
TempLogger::TempLogger(int x):pin(x),thermo(x){}
In your code, you are declaring another variable called thermo thus hiding your class-member variable.
One thing you are definitely doing wrong is in the constructor
TempLogger::TempLogger(int x) {
pin = x;
OneWire thermo(pin); //This creates a local object inside the constructor which gets deleted directly after this statement
}
You might want to do this instead :-
class TempLogger {
private:
int pin;
OneWire *thermo;
public:
TempLogger(int);
float read();
};
TempLogger::TempLogger(int x) {
pin = x;
thermo = new OneWire(pin);
}

error: no matching function for call to ‘_3DVec::_3DVec()’

I can't get this constructor right (RMatrix.class.h) :
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) {
// ...
}
My main file has :
#include <iostream>
#include <math.h>
#include "classes/Color.class.h"
#include "classes/Vector.class.h"
#include "classes/RMatrix.class.h"
int main () {
// ...
}
_3DVec is defined defined in Vector.class.h and included before the RMatrix file.
Compiler throws : error: no matching function for call to ‘_3DVec::_3DVec()’.
RMatrix file code :
class RMatrix {
private:
_3DVec right;
_3DVec up;
_3DVec out;
double spin;
double MData[16];
public:
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) {
// stuff...
}
}
Thanks
The compiler is telling you that somewhere in your code the default constructor of _3DVec class is needed. And class _3DVec does not have a default constructor. Hence the error.
In the code you posted RMatrix members right, up and out are default-constructed by RMatrix constructor. So, this is exactly where the default constructor is required.
I could make a guess that constructor parameters are supposed to be used as initializers to your vectors, as in
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) : up(Wup), out(Out) {
// stuff...
}
The above takes care of up and out by copy-constructing up and out, but that still leaves your right default-constructed. And that is still a guess. Only you know how what your class members are supposed to be initialized with.
P.S. Note also that in C++ language global-namespace names that begin with _ are reserved to implementation. You are not allowed to use such names in global namespace.

C++ Access violation when passing variable

Heres my problem, if I pass a variable from class A to class B via function, then in class B pass that variable to other functions for testing then it works fine.
But if I pass the variable from A to B then try assigning it to a variable in class B, it gives the error for no reason
//Globals.h
enum TypeofObject { CIRCLE, SQUARE, RECTANGLE, DIAMOND };
//Object.h
#include "Globals.h"
class Object
{
void Update();
private:
TypeofObject currentObject;
CollisionDetection * gameCollision;
};
//Object.cpp
void Object::Update()
{
//Do stuff here
gameCollision -> testCollision(currentObject);
}
//CollisionDetection.h
#include "Globals.h"
class CollisionDetection
{
public:
void testCollision(TypeofObject currentObject);
private:
void checkObjects(TypeofObject currentObject);
TypeofObject currentObject;
}
//CollisionDetection.cpp
void CollisionDetection::testCollision(TypeofObject curObject)
{
currentObject = curObject; //<- If I have this then it gives access violation error
checkObjects(curObject); //<- Passing it from one function to the next works
//fine but I want to assign it to currentObject so
//it doesnt need to be passed
}
I assume the issue here is that Object::gameCollision has not been initialised. The CollisionDetection::testCollision function is called correctly because you can imagine member functions as regular function taking an extra hidden parameter:
void CollisionDetection_testCollision(CollisionDetection *this,
TypeOfObject curObject);
Given your definition, the function will run correctly up until the point where this is accessed:
currentObject = curObject; // this->currentObject = curObject
The line above is trying to set some memory at an offset from the this object. If this is not correctly initialised, the function will fail with an access violation.
I presume that checkObjects(curObject) does not fail because you are not accessing any of the data members of CollisionDetection in that function.

C++ redefinition

I am trying to implement a function class, but got a error of redefinition. I know it is stupid, but can anyone please help?
=== header file ===
#ifndef _NS4_h
#define _NS4_h
#include <vector>
#include <list>
namespace NS4{
class complex{
double r, i;
public:
complex(double a=0, double b=0) : r(a), i(b) {};
complex operator+(complex c);
complex &operator+=(complex c);
complex &operator=(complex c);
};
// function class
class Add{
complex val;
public:
Add(complex c){ val = c; }
Add(double r, double i) { val = complex(r, i); }
void operator()(complex& c) const { c += val; }
};
void h(std::vector<complex> &aa, std::list<complex> ll, complex z);
}
#endif
=== Part of the cpp file ===
using namespace NS4;
void test9()
{
vector<complex> aa;
aa.push_back(complex(0,1));
aa.push_back(complex(0,2));
aa.push_back(complex(0,3));
list<complex> ll;
ll.push_back(complex(1,1));
ll.push_back(complex(1,2));
ll.push_back(complex(1,3));
complex zz(1,1);
// the following line is not working
// error C2371: 'zz' : redefinition; different basic types
Add(zz); // Add(complex(1,1)) is working.
h(aa,ll, zz);
}
You have an Add class, so you need to create an instance of it, in order to call the constructor.
So in the below case, a is an instance of our Add class.
Add a(zz);
You can optionally put parenthesis around the variable name in a declaration.
int (i);
is the same as
int i;
So in your case you are declaring a variable named zz of type Add, and a variable named zz already exists. You probably meant to pass zz as an argument to Add constructor, but then you should give some name to the variable:
Add adder(zz);
However, I don't see where that instance is used at all.
But if you just want to invoke the constructor of Add without declaring a variable, you can put parenthesis around the whole expression:
(Add(zz)); //just calls Add::Add(Complex);
Welcome to C++ ;)
What is Add(zz) supposed to mean? What do you think it means?
Add(zz) is actually a declaration of object zz of type Add, i.e.
Add(zz);
is equivalent to
Add zz;
You have already defined zz before, which is why you get the redefinition error. No surprise here.
There's no way to help you further without knowing what you were trying to do by that Add(zz) line.