I have a custom data type array and vector as below. In Foo function i started to fill array and vector with data. Anyway there was no problem filling array with data. However i couldn't access anything with vector. I could not find what i am missing .
Is there a way to fill the vector objects with data.
// MyClass.h
#include <cliext/vector>
using namespace System;
using namespace cliext;
public ref class MyClass {
private :
static int x ;
static float y ;
String ^name;
public :
static array<MyClass ^> ^myArray = gcnew array <MyClass^> (3) ;
static vector<MyClass^> ^myVector = gcnew vector <MyClass^> (3) ;
void Foo();
};
// MyClass.cpp
#include "stdafx.h"
#include <MyClass.h>
void MyClass::Foo()
{
myArray[0] = gcnew MyClass;
myVector[0] = gcnew MyClass;
myArray[0]->x = 100 ;
myArray[0]->x = 99.5 ;
myArray[0]->name = "Good" ;
myVector[0]->CAN'T ACCESS ANY CLASS DATA MEMBER !!
}
Here's the MSDN explaining what's happening: How to: Expose an STL/CLR Container from an Assembly
"STL/CLR containers such as list and map are implemented as template ref classes. Because C++ templates are instantiated at compile time, two template classes that have exactly the same signature but are in different assemblies are actually different types. This means that template classes cannot be used across assembly boundaries."
As I understand it, your public class is attempting to export a template specialization of vector but this will have a different signature from an external declaration of the same vector and would never match.
You may want to change the myVector element like this (which compiles for me):
static cliext::vector<MyClass^>::generic_container ^myVector = gcnew cliext::vector<MyClass^>(3);
Another option is to not mark your class as 'public' so the compiler doesn't attempt to make it usable outside of your assembly.
I'll also note that using 'static' on x and y seems suspect to me. You sure you only want one of those?
Related
as i am seeking to reduce the compile times of our code, i am currently trying to reduce heavy includes in header files. For this, i am forward declaring function parameters as in this example:
// Class A.h
class B;
class A
{
...
void foo(B);
}
However, i did not find a way to forward declare our typedefinitions, that rely on boost units such as the definition of a length unit (Length.h) required as a function parameter in the file Object.h:
// Length.h
using meter_unit = boost::units::si::meter_base_unit::unit_type;
using Length = boost::units::quantity<meter_unit, double>;
BOOST_UNITS_STATIC_CONSTANT(Meter, meter_unit);
BOOST_UNITS_STATIC_CONSTANT(Meters, meter_unit)
// Object.h
#include <Length.h> // This include shall be avoided
class Position;
class Object {
...
bool isNearby(Position pos, Length distance);
}
Are there any suggestions on how i could achieve this?
What I Tried:
First Approach: I tried forward declaring the template boost::units::quantity<meter_unit, double>;
but i struggeld to define the meter_unit that contains both template class meter_base_unit and unit_type inside the namespace of meter_unit.
The meter_base_unit is defined inside boost units as below (simplified) and i guess the unit_type is defined inside the macro BOOST_TYPEOF_REGISTER_TYPE.
// Boost ... Units/Meter.hpp
namespace boost::units::si {
struct meter_base_unit : public base_unit<meter_base_unit, length_dimension, -9>
{
static std::string name() { return("meter"); }
static std::string symbol() { return("m"); }
};
}
}
BOOST_TYPEOF_REGISTER_TYPE(boost::units::si::meter_base_unit)
Is such a constellation even possible to forward declare? And if not, do alternatives exist that could have the same benefit (avoided include while still using the Boost Units Library).
Second Approach: Defining classes that inherit from the respective units such as:
class Length : public boost::units::quantity<meter_unit, double>
but the problem is, that i then have to create CTR for every possible unit that i try to initialize the Length unit with (Feet, Meter, Kilometer a.s.o), which is basically re-implementing the library.
Third Approach: Creating a class that contains only the length unit as a variable, which then leads to overloading all possible operators for that class.
I am happy for every contribution regarding my specific problem and every contribution leading to deeper understanding of template forward declarations.
Thanks in Advance
SegfaultCreator
So I have a huge amount of classes (20+ that I want to store into a map array as such:
mapArray['ClassName'] = new ClassName();
I thought about doing something like
App::setup() {
mapArray['ClassName1'] = new ClassName1();
mapArray['ClassName2'] = new ClassName2();
mapArray['ClassName3'] = new ClassName3();
}
However I think that is inefficient. I was thinking on how I would go about doing this, I was thinking to use preprocessor directives. Something like this
#define DECLARE_CLASS(ClassName)
mapArray[ClassName] = new ClassName();
However, with this approach I would still need to to call that multiple time within the same function or something.
How would I go about adding all the classes to the same array but without calling the same code multiple time within the same function? So that the code isn't repetitive.
Using
App::setup() {
mapArray['ClassName1'] = new ClassName1();
mapArray['ClassName2'] = new ClassName2();
mapArray['ClassName3'] = new ClassName3();
}
is not a good idea (even after you fix the incorrect syntax of trying to use single quotes to define a string). It breaks the Open/Closed Principle. If you want to add ClassNameN to your system, you have to come back to modify a working function.
It's better to use a registration mechanism. Declare a function, registerObject, as:
App::registerObject(std::string const& name, BaseClass* ptr);
and implement it as:
static std::map<std::string, BaseClass*>& getClassMap()
{
static std::map<std::string, BaseClass*> theMap;
return theMap;
}
App::registerObject(std::string const& name, BaseClass* ptr)
{
getClassMap()[name] = ptr;
}
and then, in the source file that contains the implementation of ClassNameN, make sure to call
App::registerObject("ClassNameN", new ClassNameN());
One way to register:
Use a helper class called Initializer, which is defined in the .cpp file.
Make the call to App::registerObject in the constructor of `Initializer.
Create a file scoped static instance of Initializer in the .cpp file
ClassName1.cpp:
#include "ClassName1.hpp"
// You can use anonymous namespace but I prefer to use a named
// namespace. It makes names of the typeinfo object clearer.
namespace ClassName1NS
{
struct Initializer
{
Initializer();
};
}
using namespace ClassName1NS;
static Initializer initializer
Initializer::Initializer()
{
App::registerObject("ClassName1", new ClassName1());
}
I am trying to write my code without using global variable as most people told me it was a bad habit, so I am changing how my program works.
I am having problem with passing multiple instance of a class to another class. I need to be able to modify the multiple instance of a class in the other class.
Here is what I am trying to do but failing miserably at it :
int main() {
Players *player[6];
//preparing 6 instances of Players() so I can loop through them in another class
for (int i = 0;i<6;i++){
player[i] = new Players();
}
player[0]->name = "fluffy";
Players.h
#ifndef PLAYERS_H_
#define PLAYERS_H_
#include <string>
#include <vector>
class Players {
public:
Players();
virtual ~Players();
std::string name;
bool hand;
int cif;
int id;
std::vector<int> autho;
std::vector<int> collec;
std::vector < std::vector <int> > puppet;
};
#endif /* PLAYERS_H_ */
Players.cpp
#include "Players.h"
Players::Players() {
// TODO Auto-generated constructor stub
name = "";
hand = false;
cif = -1;
id = -1;
}
Players::~Players() {
// TODO Auto-generated destructor stub
}
Now I want to call another class (doesn't matter which) and I want to pass the multi instanced class Players to it so it can read and do modification to the data within these instanced classes.
For example a class with a function that could read player[0]->name and modify it to "sandpaper"
How would you approach this without getting errors from the compiler?
I am open to suggestion for a completely different way to approach this ( I have tried to use struct variables and pass it but I got other problems as well)
thank you,
Kaven
First of all, I'd approach this by using std::vector<Players> (not pointers!). Secondly, I'd just pass this vector by reference to other functions.
I suggest to approach like this:
int main()
{
unique_ptr<vector<Player>> playersVector (new vector<Player>);
for (int i = 0;i<6;i++)
{
playersVector->push_back(Players());
}
playersVector->at(0).name = "fluffy";
}
And then if you want to pass that vector with ownership to some method or class use:
move(playersVector)
If you want have ownership in main class pass by normal pointer:
playersVector.get()
I also suggest using Get/Set methods instead of accessing class fields directly
I'm writing a dll, which contains a c++ class definition, and a core program based on the proxy pattern, as described in this tutorial: http://www.linuxjournal.com/article/3687
Specifically, this dll, after is loaded on the core program, will fill its definition including the class's name, method's name, and method's function pointer in the data structure of the core program.
However, I want to modify this pattern for the different kinds of classes, instead of only one base kind in the article, which is the reason why I use the function pointer.
My program is as following:
//the base class
class common_object{
};
//this factory is used for storing constructor for each c++ class in the dll.
typedef common_object *maker_t();
extern map< string, maker_t* > factory;
//store all the methods of a class
//string: method's name
typedef map<string, proxy::method> method_map;
//string: class's name
extern map<string, method_map> class_map_;
// our global factory
template<typename T>
class proxy {
public:
typedef int (T::*mfp)(lua_State *L);
typedef struct {
const char *class_name;
const char *method_name;
mfp mfunc;
} method;
proxy() {
std::cout << "circle proxy" << endl;
// fill method table with methods from class T
// initialize method information for the circle class
method_map method_map_;
for (method *m = T::methods;m->method_name; m++) {
/* edited by Snaily: shouldn't it be const RegType *l ... ? */
method m1;
m1.class_name = T::className;
m1.method_name = m->method_name;
m1.mfunc = m->mfunc;
method_map_[m1.method_name] = m1;
}
//register the circle class' description
class_map_[T::class_name] = method_map_;
}
};
In this program, I extern two data structs of the core problem:
class_map: contain all the class in the dll loaded in the core
program. method_map:
method_map: contains all the methods'description for each
class.
the relation between class_map and method is one-to-many.
However, I run into a problem of declaration order of class_map_ and method_map. Specifically, I extern class_map outside the class Proxy, but I also have to define the method structure inside this class.
I tried to use forward declaration in the following link: When can I use a forward declaration?, but it doesn't work.
I hope to see your solution about my problem. Thanks so much
hello every i have made a structure and i want to make 2 objects of it . i am using qtcreator.
i write
struct grapharray gao ; (grapharray is my structure)
every thig works well but when i write another object like
struct grapharray gao ;
struct grapharray gao1 ;
my program unexpectedly finishes can any one tell me why is it so and where should i declare the struct object
struct grapharray
{
int structcol;
double *structpayloadgraph;
double *structsessiongraph;
};
here is my structure;
and i have a function
struct grapharray graphplotdata(char * filename)
{ // computing some values and returning structure object
}
thanks
If I understand well the problem, I would say that you use far too much the "struct" keyword.
If you define your struct as
struct grapharray
{
int structcol;
double *structpayloadgraph;
double *structsessiongraph;
};
then you don't need to use the keyword "struct" when declaring the variables.
grapharray gao; // without struct keyword
grapharray gao1; // without struct keyword
and your function should be
grapharray graphplotdata(char * filename) // without struct once again.
{
// computing some values and returning structure object
}
structs does works almost the same way as classes; the main difference is that structs members and methods are "public" by default and classes members and methods are "private" by default.
Edit: Considering the comment of Dennis Zickefoose, this is not the good answer.