Pass new object into function - c++

I have a function: Vector::Vector integrate(Vector::Vector start, Vector::Vector end, long int elapsedtime);, where a Vector is a class I've created:
class Vector {
public:
double x, y, z;
Vector();
Vector::Vector addToSelf(Vector &right);
};
I want to call integrate with a blank Vector for it's first parameter. The constructor for the Vector does this by default, so I'm trying to do this:
acceleration = integrate(Vector::Vector blank, wc.readAccelerometer(), time);.
However, this gives me errors:
error: expected primary-expression before ‘blank’.
I thought perhaps I didn't need to give the Vector a name when I create it in the integrate function call:
acceleration = integrate(Vector::Vector, wc.readAccelerometer(), time);
but this gives me the same error:
expected primary-expression before ‘,’ token.
I could always pass in a pointer, change the integrate signature to match, but this seems unnecessarily messy. I could also create a new Vector, then pass it to integrate:
Vector::Vector blank;
acceleration = integrate(blank, wc.readAccelerometer(), time);
which works without errors, but I would have thought doing it on one go would be possible. What am I doing wrong?
EDIT: Thanks to Karl von Moor's comment, I've fixed it - change Vector::Vector to Vector (because I'm not defining namespaces) and everything works. Thanks.

This line is not correct C++ syntax:
acceleration = integrate(Vector::Vector blank, wc.readAccelerometer(), time);
To create a default-constructed Vector object, use Vector():
acceleration = integrate(Vector(), wc.readAccelerometer(), time);
In C++11, you can also write Vector{} or even {} to construct a value-initialized object.
Note that usually you want to pass "large" objects by reference to const to avoid unnecessary copies. So try changing your declaration of integrate to:
Vector integrate(const Vector& start, const Vector& end, long int elapsedtime);

Don't use scope resolution operator in a class declaration and function's parameter names. So remove Vector:: until you are not defining the function. Example :
// declaration
class A {
A();
void f(int x);
};
// definitions
A::A(){/*...*/};
A::f(int x){/*...*/}; //note that the parameter x doesn't have a `::`

Related

occur no matching function for call to error in c++

I'm a novice in c++, i know there is a lot of similar questions but unfortunately didn't help me to solve this problem (which is a conceptual misunderstood i think)
So i have this constructor
Field::Field(const Position &posG, const Position &posC) {
//...
}
And i am creating a Field as follows
// Create positions
Position posG, posC;
posG.x = 3;
posG.y = 3;
posC.x = 4;
posC.y = 4;
// Create pointers to positions
const Position *pPosC(&posC);
const Position *pPosG(&posG);
// Create field
Field field (pPosG, pPosC);
Where position is
struct Position {
int x;
int y;
};
Then i am getting this exception:
main.cpp:27:30: error: no matching function for call to ‘Field::Field(const Position*&, const Position*&)’
Field Field (pPosG, pPosC);
In file included from main.cpp:2:0:
Any help? Regards
Field(const Position &posG, const Position &posC);
^^^^^ ^^^^^^
Those are references. So when you try to pass pointers
Field field (pPosG, pPosC);
^^^^^ ^^^^
pointer pointer
It can't compile.
Either make the constructor accept reference pointers (const Position *&posG) or pass the value of the pointers (*pPosG), or just pass the values directly (posG).
When you have a constructor defined as
Field(const Position &posG, const Posicion &posC);
You can use objects of type Position as arguments to it, not pointers to Position.
You can use:
Field field(posG, posC);
or
Field field(*pPosG, *pPosC);
Your constructor expects references, not pointers.
As a sidenote, it's not clear why you use references or pointers.
you must define a constructor, then use of const Position *pPosC(&posC); expression.
you must define constructor-copy like this :
struct Posicion {
public :
Position(const Position &pos) // constructor copy
{
// some code here
x = pos.x;
y = pos.y;
}
int x;
int y;
};

Returning a whole class of information inside a function

so I've been working on a program where I have a class called CDistance, here it is,
class CDistance
{
private:
int feet, inches;
public:
CDistance();
CDistance(int, int);
void setDist();
void printDist() const;
CDistance add(const CDistance&) const;
};
part of what I need to do is to create an array of 5 of these objects, set the feet and inches on each one of them, and then add them together without changing the original variables. This is the function definition, as you can see, it's working with all constant members, so it's a matter of figuring out how to reference the variables, but most importantly, getting them back into a CDistance type to be returned. Should I create a new CDistance type within this function to work with the ref
CDistance CDistance::add(const CDistance&) const
{
}
That's where I've been stuck, I'm kind of confused about the whole pointers and encapsulation deal. I'm new to programming, and have learned that the hard way, but if someone could help me out with this, I would really appreciate it
Should I create a new CDistance type within this function to work with the ref
Yes, you'll need a new object to modify and return:
CDistance add(const CDistance& other) const {
CDistance result = *this; // Copy this object
result.feet += other.feet; // Add the other object...
result.inches += other.inches; // ... to the copy
return result; // Return the copy
}
Note that this isn't complete; there's one deliberate error, and an unknown number of accidental errors, which you'll need to fix yourself.
You can simply return a local result instance from your function:
CDistance CDistance::add(const CDistance& other) const
{
CDistance result(*this);
// Calculate the result using result.feet, result.inches and
// other.feet, other.inches
return result;
}

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?

C++ pass by pointer

Guys, I am very new to c++. I have just wrote this class:
class planet
{
public:
float angularSpeed;
float angle;
};
Here is a function trying to modify the angle of the object:
void foo(planet* p)
{
p->angle = p->angle + p->angularSpeed;
}
planet* bar = new planet();
bar->angularSpeed = 1;
bar->angle = 2;
foo(bar);
It seem that the angle in bar didn't change at all.
Note that you are passing bar by pointer, not by reference. Pass-by-reference would look like this:
void foo(planet& p) // note: & instead of *
{
p.angle += p.angularSpeed; // note: . instead of ->
}
Pass-by-reference has the added benefit that p cannot be a null reference. Therefore, your function can no longer cause any null dereferencing error.
Second, and that's a detail, if your planet contains only public member variables, you could just as well declare it struct (where the default accessibility is public).
PS: As far as I can see it, your code should work; at least the parts you showed us.
Appearances must be deceptive because the code should result in foo(bar) changing the contents of the angle field.
btw this is not passing by reference, this is passing by pointer. Could you change the title?
Passing by reference (better) would be
void foo(planet& p) {
p.angle += p.angularSpeed;
}
planet bar;
bar.angularSpeed=1;
bar.angle=2;
foo(bar);
You might also consider a constructor for planet that takes as parameters the initial values of angle and angularSpeed, and define a default constructor that sets them both to 0. Otherwise you have a bug farm in the making due to unset values in planet instances.

How do I pass a Generic::List by reference?

In an attempt to wrap some unmanaged code in a managed .dll I'm trying to convert a Generic::List of data points into a std::vector. Here's a snippet of what I'm trying to do:
namespace ManagedDLL
{
public ref class CppClass
{
void ListToStdVec( const List<double>& input_list, std::vector<double>& output_vector )
{
// Copy the contents of the input list into the vector
// ...
}
void ProcessData( List<double> sampleData )
{
std::vector<double> myVec;
ListToStdVec( sampleData, myVec );
// Now call the unmanaged code with the new vector
// ...
}
}
}
Compiling this gives me:
error C3699: '&' : cannot use this indirection on type 'const System::Collections::Generic::List'
I've probably missed something fundamental here (I'm relatively new to .net's way of doing things), but that looks like reasonably valid code to me.. ?
[Edit] I've tried both Andy and Dario's suggestions and they work, but how do I then access the members of the input list? I've tried all sorts of combinations of dreferencing and nothing seems to compile:
void ListToStdVec( const List<double>% input_list, std::vector<double>& output_vector )
{
int num_of_elements = input_list->Count;
}
void ListToStdVec( const List<double>^ input_list, std::vector<double>& output_vector )
{
int num_of_elements = input_list.Count;
}
...both give me:
error C2662: 'System::Collections::Generic::List::Count::get' : cannot convert 'this' pointer from 'const System::Collections::Generic::List' to 'System::Collections::Generic::List %'
...so how do you access the reference / pointer?
According to Herb Sutter, % is the managed object pass by reference character. Convert the code to the following, and it should work:
void ListToStdVec( const List<double>% input_list, std::vector<double>& output_vector
{
// Copy the contents of the input list into the vector
// ...
}
Edit: I think the const is causing the issues, although I'm not sure why. If you change the List argument to not be const, then the first function will compile if you use the -> operator, while the second function will compile if you use the . operator (I'm not sure why that difference exists - it doesn't make much sense).
That said, if all that you want to do is to copy the elements in the List to the vector, then you really want to use ^. Think of that as having a reference to the managed object. I think that % would be used if you want to pass the reference "by reference" (i.e. reassign input_list to something else within ListToStdVec(), and have the caller see the result of that assignment. However, given that you use the . operator to access members when using %, that tells me that I may not understand the purpose of that at all.
As List<T> is a managed .NET class, it's passed by managed GC-Handle denoted by ^ and not by C++-reference.
Ex:
void ListToVec(List<double>^ input_list, std::vector<double>& out)
You don't need additional const here. The notation List<T>^% creates a tracking reference (comparable to C++-pointers) rather than a call by reference.
Just access the members by list->... and list[...].