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

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.

Related

Initializing array of Objects in C++ Composition

I wanted to design a composition using C++ as shown below:
#define NUMBER (4)
class wheel {
int radius;
public:
wheel();
wheel(int);
//copy constructors prototype
//getters and setters prototypes
};
wheel::wheel() : radius(1) {}
wheel::wheel(int r) : radius(r) {}
//wheel class copy constructor definition
//wheel class setter and getter definitions
class car {
wheel fourwheels[NUMBER];
public:
car();
};
car::car() {
fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //error code
//wheel fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //non-error code
}
int main() {
car mycar;
return 0;
}
While compiling the code, I am getting the following error:
error: no match for 'operator=' (operand types are 'wheel' and '<brace-enclosed initializer list>')
Queries:
Why does this error occur ??
When I comment the error code line and uncomment the non-error code line, it works fine. Why do we have to add the type wheel for the array definition?
You are attempting to assign to an array element. And one that's out of range at that.
Using the constructor's initializer list, this will compile, though you should consider using STL containers rather than a raw array.
car::car() : fourwheels{wheel(1), wheel(1), wheel(1), wheel(1)}
{
}
The code you had commented out "worked" because it declared and initialized a new array of four wheels.
Since the default constructor for wheel provides a radius of 1, you could also write:
car::car() : fourwheels{wheel(), wheel(), wheel(), wheel()}
{
}
But, if we used std::array to hold our wheels, we can simplify this further, as the elements of fourwheels will be initialized using the wheel type's default constructor, which we don't have to write.
class car {
std::array<wheel, NUMBER> fourwheels;
};
Why does this error occur ??
Raw arrays are not copy-assignable. That is, the following will not work:
int nums[4] = {};
nums = {1, 2, 3, 4};
That is essentially what you're trying to do in your car constructor. Instead, you need to initialize the fourwheels member in the member initialization list:
car::car()
: fourwheels{wheel(1), wheel(1), wheel(1), wheel(1)}
{}
When I comment the error code line and uncomment the non-error code line, it works fine. Why do we have to add the type wheel for the array definition ??
Because you're not initializing your car class's member there. You're declaring and initializing a different array, also named fourwheels that is local to the constructor body. The class member remains default-initialized.

C++ Private variable of a class is a pointer. How do i have to write setter ? + enumeration

Hi everyboy :) I m pretty new on programming and especially on C++.
This is why I am trying to test some beginners functions like getters and setters with private variable which are, in fact, pointers. I m doing this tests for an assignement and i have to use enumeration too.
I got 0 compilation error but my test program is crashing when i m trying to set my private pointer with an enum type.
Here is my class "Slot": header file : Slot.hpp
#ifndef SLOT_H
#define SLOT_H
enum Pawn{YELLOW, RED};
class Slot
{
public:
Slot();
~Slot();
Slot(const Slot& slot_to_copy) {color = new Pawn(*(slot_to_copy.color));}
void setColor(Pawn);
Pawn getColor();
private:
Pawn *color;
};
#endif
Here is my source file: Slot.cpp:
#include <iostream>
#include "Slot.hpp"
using namespace std;
Slot::Slot() {color = NULL;}
Slot::~Slot() {}
void Slot::setColor(Pawn col)
{
*color = col;
}
Pawn Slot::getColor()
{
return *color;
}
And here is my main where I am testing the getter and the setter:
#include <iostream>
#include "Slot.hpp"
using namespace std;
int main()
{
Slot test;
test.setColor(YELLOW); // testing the setter
Pawn coin = test.getColor(); // testing the getter
if (coin == YELLOW)
cout <<"SUCCESS"<< endl;
return 0;
}
My problem is located on the setter function ...
Thank you in advance for your help, i already took 3 hours by trying to fix my problem and I cannot work on my assignement without this working correctly :/
Sorry for my approximate English by the way.
PS: I HAVE TO use pointer for that, because it is asked by my teacher and consist in the difficulty (or at least a part of it) of our programming assignement.
Your default constructor Slot() doesn't allocate space for the Pawn *color, so it'll just point to some random location in memory. When you write to it you'll write to this random location.
You can set it like this:
Slot::Slot() : color(new Pawn)
{}
Here we're using the member initializer list to set color to allocated memory before the body of the constructor is executed. It's conceptually the same as saying:
Slot::Slot()
{
color = new Pawn;
}
For integral types and pointers there's not much difference. However, if the member variables were class instances then the member variable initializer list is the only way to initialize classes that do not have a default constructor.
However, since enum is effectivly an int there's no point is using a pointer. Just declare it as:
Pawn color;
And get/set it like this:
void Slot::setColor(Pawn col)
{
color = col;
}
Pawn Slot::getColor()
{
return color;
}
You are not initializing the pointer in the default constructor. This means de-referencing it is undefined behaviour. You should make it point to something you can write to later:
Slot::Slot() : color(new Pawn()) { }
Note that having a class manage dynamically allocated resources means it has to do sensible things in its copy constructor, assignment operator, and destructor. See the rule of three.
The easiest solution in not to use a pointer at all:
....
private:
Pawn color;
Your color pointer is being assigned to something only in copy constructor, while in your main you are creating Slot using default constructor, that's why pointer stays uninitialized and behaviour of functions like setColor is undefined.

Initialize a dynamic vector list

I am trying to initialize my MedList but it's not working. Here's what I'm talking about:
repository.h
#include "../domain/farmacy.h"
#include "../utils/DynamicVector.h"
class Repository{
private:
DynamicVector<Medicine>* MedList; //I made it pointer so it can be dynamic
public:
Repository(); //constructor
repository.cpp
#include "../domain/farmacy.h"
#include "repository.h"
#include "../utils/DynamicVector.h"
#include <stdlib.h>
Repository::Repository(){
this->MedList=new DynamicVector<Medicine>::DynamicVector(); //error
}
DynamicVector.h
template <typename Element> //this is the Dynamic Vector constructor
DynamicVector<Element>::DynamicVector()
{
this->cap=10;
this->len=0;
this->elems=new Element[this->cap];
}
the error above is:
Multiple markers at this line
- no match for 'operator=' in '((Repository*)this)->Repository::MedList = (int*)operator
new(4u)'
- expected type-specifier
- candidate is:
- expected ';'
this is the medicine class
class Medicine{
private:
int ID;
std::string nume;
double concentratie;
int cantitate;
The Dynamic Vector class:
template <typename Element>
class DynamicVector{
private:
Element* elems;
int cap;
int len;
void resize();
void CopyToThis(const DynamicVector& v);
public:
DynamicVector(); //constructor implicit
DynamicVector(const DynamicVector& ); //constructor de copiere
DynamicVector& operator=(const DynamicVector& );
~DynamicVector();
void addElement(Element elem);
Element delElementAtPosition(int pos);
Element getElementAtPosition(int pos);
int getLen();
};
What am I doing wrong? I tried a lot of variants but nothing seems to work. Could you help me?
I think you're confusing c++ syntax for creating object with some other language, e.g. Java or C#.
In c++, a constructor is called simply by declaring the variable:
DynamicVector<Element> medList; // Calls DynamicVector<Element>::DynamicVector()
The new operator in C#, is to dynamically allocate space for a variable, and returns a pointer to the allocated space. To use it here, you'd have to declare Repository::MedList as a pointer type, and initialize it like so:
DynamicVector<Medicine>* MedList; // in repository.h
this->MedList = new DynamicVector<Medicine>(); // in repository.cpp
However, as Andy Prowl pointed out, it is much better to just let the compiler do the memory management for you. To do so, you should completely remove the erroneous line in repository.cpp. Why? Well, when the repository is constructed, the compiler also tries to construct all member objects using their default constructors. This is exactly what you want, so there is no reason to try to alter the compiler's behavior.
Constructor should be:
Repository::Repository(){
this->MedList=new DynamicVector<Medicine>;
}
DynamicVector() calls the constructor for DynamicVector.
DynamicVector::DynamicVector() is a pointer to the address of the constructor function
The chances are your C++ version doesn't allow empty () for constructors.
this->MedList=new DynamicVector<Medicine>::DynamicVector(); //error
should be
this->MedList=new DynamicVector<Medicine>::DynamicVector;
or (The usual way of writing it)
this->MedList=new DynamicVector<Medicine>;
See here for more info.
EDIT. Make sure you have declared the dynamicVector constructor in the class.
Default constructor with empty brackets
Do the parentheses after the type name make a difference with new?

Trouble instantiating class with reference to another class

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) {}

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.