C++/CLI - Error C2664 again - visual-studio-2010

I am dealing with following problem. To be formal I am using VS2010 Ultimate and I try to write an windows forms application, but I get specified error:
1>f:\baza danych\baza\baza\Form5.h(475): error C2664: 'Bazadanych::Dodaj1' : cannot convert parameter 1 from 'Car' to 'Car'
1> Cannot copy construct class 'Car' due to ambiguous copy constructors or no available copy constructor
and here are Car.h where I have declaration of this class
public ref class Car
{
public:
String^ category;
String^ model;
String^ rocznik;
String^ cena;
Car(){};
Car(String^ ,String^ ,String^ );
void edytuj(String^ ,String^ ,String^ );
String^ getmodel(){return this->model;};
String^ getrocznik(){return this->rocznik;};
String^ getcena(){return this->cena;};
virtual String^ getcat()
{
this->category="To rent";
return this->category;
};`
}
Definition:
Car::Car(String^ model1,String^ rocznik1,String^ cena1)
{
this->model=model1;
this->rocznik=rocznik1;
this->cena=cena1;
};
void Car::edytuj(String^ model1,String^ rocznik1,String^ cena1)
{
this->model=model1;
this->rocznik=rocznik1;
this->cena=cena1;
};
Declaration of class where method mentioned in error is:
public ref class Bazadanych
{
public:
cliext::list<Car^> Bazatorent;
cliext::list<Rented^> Bazarented;
cliext::list<Unavaible^> Bazaunavaible;
cliext::list<Car^>::iterator it1;
cliext::list<Rented^>::iterator it2;
cliext::list<Unavaible^>::iterator it3;
Bazadanych()
{
it1=Bazatorent.begin();
it2=Bazarented.begin();
it3=Bazaunavaible.begin();
};
bool Empty();
void Dodaj1(Car);
void Dodaj2(Rented);
void Dodaj3(Unavaible);
void Usun1(Car);
void Usun2(Rented);
void Usun3(Unavaible);
void Czysc();
};
and definition:
void Bazadanych::Dodaj1(Car Element)
{
this->Bazatorent.push_back(Element);
};
I have definitions and declarations in separatly .h and .cpp files. For other methods "Dodaj" and "Usun" I have exactly the same problems. If it could help the class Car is base class for class Rented and Unavaible.
I am pretty new in C++/CLI, so I will be very grateful if someone could help me.

I find the error message strange given that it's a managed class. But you can solve it by changing the method's signature to:
void Bazadanych::Dodaj1(Car^ Element) // notice the "^"
Same for the other similar methods.
I'm guessing that without the hat (^), the compiler treats the variable as a regular C++ class, and therefore requires a copy constructor for it, even though managed classes don't even have copy constructors (you can write them but they're never called implicitly like for regular C++ classes).
EDIT: About the error in your comment: Instead of instantiating the class like this:
Car car;
Do it like this:
Car^ car = gcnew Car();

It says what it means: you have no copy constructor for Car. It might look like this:
Car::Car(const Car& c) {
/* your code here*/
};
Some background here and here.

Related

C++: convert not from obj1 to obj2, but from obj1* to obj2?

A constructor for MyClass takes a pointer to another such object.
The C++ MyClass is functionally the same as a C "class" based on a typedef'd struct called MyType_T. (The C++ class is basically a wrapper to the old C code.) I'd like to be able to pass in a MyClass* anywhere I could pass in a MyType_T* before.
I'd like to write an automatic conversion of any MyClass* to MyType_T*, but I guess what's throwing me is that my type converter is written to take a MyClass not a MyClass*. Even though I'm sure that's the problem, I can't think of what syntax would solve it. I've thought about making a friend implementation of the cast, but I can't put it before the definition of class MyClass because it won't know the offset of thing. And I can't put after the definition of class MyClass because the MyClass constructor wants to use that conversion.
typedef struct MyStruct {
int iFoo;
struct MyType* ptypeParent;
} MyType_T;
void MyTypeCreator( MyType_T* ptypeSelf, int iFoo_in, MyType_T* ptypeParent );
class MyClass {
public:
MyClass( int iFoo, MyClass* pclassParent ) {
MyTypeCreator( &thing, iFoo, pclassParent ); <--------------- PROBLEM
MyTypeCreator( &thing, iFoo, &pclassParent->thing ); <------- WORKS
};
operator MyType_T*() { return &thing; } <---------------- INCORRECT: attempts to convert MyClass, not MyClass*, to MyType_T*.
MyType_T thing;
};
QUESTION 1: how to write a convertor from MyClass* instead of MyClass?
QUESTION 2: how can such a convertor check for NULL input? (If thing isn't offset of 0, but say 8, then converting from a NULL pclass without a check would give a value of 0x00000008, not NULL...)

How to call a class function which only argument is &

Here's my code:
class Patient {
public:
const int patientId;
const PatientKind kind;
const bool hasInsurance;
std::vector<ProcedureKind> procedures;
Patient(int, PatientKind, bool);
bool addProcedure(const ProcedureKind procedure);
double billing();
virtual double liability() = 0;
};
class Hospital {
public:
Patient &addPatient(const PatientInfo &);
};`
I don't know how to write:
Patient &Hospital::addPatient(const PatientInfo &)
{
}
Whatever I try to return or pass as argument gives me an error... Also, I don't understand what is this function expecting as an argument with just &?
Any kind of help / insight will be appreciated :D
Seems like you're trying to implement a header definition someone else wrote. That & means that the function expects a reference to an instance of PatientInfo. In the implementation, the only thing you have to do is to give the parameter a name like so:
Patient& addPatient(const PatientInfo& info)
{
// do whatever you need with 'info'
}
You can read more about c++ function declaration and implementation in any basic c++ text.

C++, getting name of the plugin from derived class

I have a requirement wherein, I need to create a base class which will have some pure virtual functions which would be implemented by derived classes. These virtual functions are not enough and I also need to get the name of the plugin to be given to a library from the base class which I will create.
I am using factory pattern. Basically thought that based on the plugin name I would create the instance of that particular derived class.
But, the problem here is since I am using factory pattern, until I send plugin name I would not create object and until object is created plugin name would not be known. Because of this I always see empty plugin name.
Many plugins would be derived from this common base class, it's important to know name of the plugin at runtime.
Please suggest
You need to register a factory for each plugin type in your central factory.
struct common_args {
int width; // whatever
};
struct BasePlugin {
virtual ~BasePlugin() {}
virtual std::string get_name() const = 0;
virtual void do_stuff() = 0;
};
using single_type_factory = std::function<std::unique_ptr<BasePlugin>( common_args ) >;
using plugin_factory = std::function<std::unique_ptr<BasePlugin>( std::string name, common_args ) >;
struct central_factory:plugin_factory {
central_factory(central_factory&&)=delete;
central_factory():
plugin_factory(
[this](std::string name, common_args args)
->std::unique_ptr<BasePlugin>
{
auto it = m_factories.find(name);
if (it == m_factories.end())
return {};
return (*it)(args);
}
)
{}
void register_plugin_type( std::string name, single_type_factory f ) {
m_factories[name] = f;
}
private:
std::unordered_map<std::string, single_type_factory> m_factories;
};
that is just a sketch.

Shared_ptr seems to work on copy, not on original object

I got 2 classes that represent Player and I want to keep in one of them pointer to another one.
So inside my view::Player I create pointer to logic::Player
namespace view {
class Player {
std::shared_ptr<logic::Player> m_player;
//logic::Player* m_player;
public:
void create(logic::Player& player) {
m_player = std::make_shared<logic::Player>(player);
//m_player = &player;
}
};
}
view::Player is created in view::GameState and simply initialised like this
m_playerOneView.create(m_game.getActivePlayer());
m_game is logic::Game object
logic::Game has std::vector<logic::Player>, and public method that returns active one
logic::Player& logic::Game::getActivePlayer() {
return m_players[m_activePlayer];
}
And finnaly
namespace logic {
class Player {
std::string m_name;
int position;
};
}
Now I need original object of logic::Player pointed by std::shared_ptr in my view::Player class. I could simply do that by changing that to raw pointer and it works then (2 commented lines do what I want to achieve basicly). But when I try to do this on std::shared_ptr, I seem to work on copy of logic::Player, because when I update his position for example, it changes everywhere in the game but not in view::Player. How to do that using std::shared_ptr then?

How to marshal following native C++ objects to C++/CLI?

I am a bit confused on how to marshal below mentioned C++ object to c++/CLI. Could you give me some idea?
Native C++ Classes
class HeaderMessage {
double timestamp;
string ric_code;
}
class TradeMessage {
double price;
int size;
}
class RFARecord
{
public:
RFARecord();
HeaderMessage * hMsg;
list<TradeMessage *> qMsgs;
};
My C++/CLI classes look like this
public ref class RFARecordRef
{
public:
RFARecordRef();
RFARecordRef(RFARecord *record);
HeaderMessageRef hMsg;
List<TradeMessageRef> tMsgs;
private:
RFARecord *record;
};
ref class HeaderMessageRef
{
private:
HeaderMessage *hMsg;
public:
HeaderMessageRef(void);
};
ref class TradeMessageRef
{
private:
TradeMessage *tMsg;
public:
TradeMessageRef(void);
};
I am not sure if my approach is correct.
I read data from a text file and transfer this data in the form of RFARecords to my C# program.
What is the right way to wrap or marshal above data objects to C++/CLI which can then be consumed by my C# program.
Thanks in advance.
Regards,
Alok
If I understand correctly. Your biggest task is going to be marshaling the strings from c++ strings into System::String^ objects.
What your going to do is declare a method in the C++/CLI class that returns a type System::String^ like so:
System::String^ get_str_from_cpp()
{
std::string str = ptr_to_native_cpp_class->get_str();
System::String^ ret_str = std_str2sys_str(str);
return ret_str;
}
The std_str2sys_str method looks like so.
static System::String^ std_str2sys_str(std::string std_str)
{
System::String^ sys_str = gcnew System::String(std_str.c_str());
return sys_str;
}
Of course you could use a char* to if you wanted to.
The "ptr_to_native_cpp_class" variable should be a class variable that points to an instance of your native c++ class. It appears you already have those.
There are also ways to marshal from the System::String^ to std::string or char* which are on the net. Hopefully this example helps though. You don't have to worry about marshalling basic types like ints or bools though, you can just return them directly from your C++/CLI layer to the C#.
To answer the question of marshalling an structure over to C++/CLI; I don't think there is a way to automatically marshal an entire custom structure, even if it is composed completely of basic types. What I do in my code is just write a wrapper object that has specific get methods for each data member like so:
//Native C++ class
class data_container
{
public:
int var1;
int var2;
}
//C++/CLI class
public ref class cli_data_container
{
public:
get_var1() {return data_ptr->var1;}
get_var2() {return data_ptr->var2;}
private:
data_container* data_ptr;
};
If there is an automatic way to do this that would be nice, but we had an intern make these interfaces for us for a few dozen utility classes last summer and they get the job done.

Resources