Managed class member varible from managed struct - managed-c++

I need help in making a member variable for a managed class of managed struct...
I tried to fix this, but the error didn't disappear till I made that class non-managed by removing "ref".
You may see this picture to see the class and the struct
http://tinypic.com/view.php?pic=149mgie&s=8
public ref struct RectResult
{
int x;
int y;
int width;
int height;
};
public ref class GullotinePackedBin
{
private:
int width;
int height;
vector<RectResult> packedRectangles;
}

Related

Storing derived classes in a vector of base class

I have seen several versions of my question, but I still cannot find an answer that works. I have defined a base class called TwoPort and two derived classes called Reflector and Waveguide as follows:
#include <vector>
class TwoPort
{
public:
TwoPort() { yeast = ywest = 0.0; }
~TwoPort() {}
double getyeast() { return yeast; }
double getywest() { return ywest; }
virtual void step(double xeast, double xwest);
protected:
double yeast;
double ywest;
};
class Reflector :
public TwoPort
{
public:
Reflector() { Gamma = 0.0; }
~Reflector() {}
void step(double xeast, double xwest) override;
void setReflection(double G) { Gamma = G; }
private:
double Gamma;
};
class Waveguide :
public TwoPort
{
public:
Waveguide() { oldest = 0; }
~Waveguide() {}
void step(double xeast, double xwest) override;
void setDelay(unsigned int delay);
private:
std::vector<double> eastBuffer, westBuffer;
unsigned int oldest;
};
My goal is to create a vector containing a mixture of Reflectors and Waveguides. Based on the answers to previous questions like mine, I have tried a number of approaches, but so far none have worked. For example:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
tpcascade.emplace_back(new Reflector);
tpcascade.emplace_back(new Waveguide);
tpcascade.emplace_back(new Reflector);
tpcascade[0]->setRefection(0.25);
}
In this case, the compiler does not recognize the setReflection method. So I tried this:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
auto ref = std::make_unique<Reflector>();
ref->setReflection(0.25);
tpcascade.emplace_back(ref);
}
In this case I can set the reflection but I get a lengthy and complex error message about the emplace statement.
Help!
Did some research and tried a variation on the second approach above:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
auto ref = std::make_unique<Reflector>();
ref->setReflection(0.25);
tpcascade.push_back(std::move(ref));
}
Switching to shared_ptr seems to work too, and is a bit cleaner:
int main()
{
std::vector<std::shared_ptr<TwoPort>> tpcascade;
auto ref = std::make_shared<Reflector>();
ref->setReflection(0.25);
tpcascade.push_back(ref);
}
This also seems to work, but seems risky to me:
tpcascade.push_back(std::make_shared<Reflector>());
std::dynamic_pointer_cast<Reflector>(tpcascade[0])->setReflection(0.25);

cppcheck out of bounds when it's not

When setting the size of a std::array in a class definition using a static const as the size, cppcheck doesn't know how large the array is. So it thinks I'm out of bounds when I'm not
Doing a #define seems to solve the problem so this is an academic question.
class A
{
A() : myArr()
{
myArr[0]=100;
}
static const int SOMEVAL = 4;
std::array<double, SOMEVAL+1> myArr;
int getVal() { return myArr[1]; };
}
int main(void)
{
A myA;
myA.getVal();
}
Any thoughts?
This was a defect in cppcheck:
https://trac.cppcheck.net/ticket/9202
Which has been fixed in the 1.89 release:
https://trac.cppcheck.net/changeset/121093658d788126d5f94792c4ea00447fdbb979/

Connecting signals coming from widgets in a QVector

I'm working on the following Window with QT:
For my rows i have the following structure:
typedef struct
{
struct{
int x;
int y;
int width;
int height;
int layer;
int idx;
}outputSettings;
QDoubleSpinBox *xSpinBox;
QDoubleSpinBox *ySpinBox;
QDoubleSpinBox *heightSpinBox;
QDoubleSpinBox *widthSpinBox;
QDoubleSpinBox *layerSpinBox;
// Checkboxes
QCheckBox *channelCheckBox;
}myUI;
QVector<myUI> inputBoxes; // Create a row of input boxes per channel
I then create them in a for loop:
for(i = 0; i < inputChannels; ++i)
{
inputBoxes[i].channelCheckBox = new QCheckBox;
inputBoxes[i].channelCheckBox->setChecked(true);
inputBoxes[i].xSpinBox = new QDoubleSpinBox;
inputBoxes[i].xSpinBox->setRange(minXPos, maxXPos);
inputBoxes[i].xSpinBox->setSingleStep(1);
inputBoxes[i].xSpinBox->setValue(0);
inputBoxes[i].xSpinBox->setDecimals(0);
connect(inputBoxes[i].xSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setXValue(double)));
inputBoxes[i].ySpinBox = new QDoubleSpinBox;
inputBoxes[i].ySpinBox->setRange(minYPos, maxYPos);
inputBoxes[i].ySpinBox->setSingleStep(1);
inputBoxes[i].ySpinBox->setValue(0);
inputBoxes[i].ySpinBox->setDecimals(0);
connect(inputBoxes[i].ySpinBox, SIGNAL(valueChanged(double)), this, SLOT(setYValue(double)));
...
Now i get stuck on the connect. I want to connect the valueChanged property of my spinboxes to my outputSettings struct. This struct will be my return type at the end.
I implemented the following slots:
public slots:
void setXValue(double x){inputBoxes[0].outputSettings.x = int(x);}
void setYValue(double y){inputBoxes[0].outputSettings.y = int(y);}
...
But here i don't know what vector item called the function. (currently i just entered inputBoxes[0] as a dummy)
My first idea was to add an extra parameter int channel. But then the connect doesn't work. So i tried to work around that with QMapper. But that doesn't seem to be a good option to me and i didn't really get it running.
I would largely appreciate if someone could help me out here or at least point me in the right direction.
Cheers.
Implement it by using a lambda function in your connect
connect(inputBoxes[i], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
[i](double value)
{
// use i as your vector index here
handleDoubleSpinBoxChanged(i, value);
});
Then you can change your slot function to
void handleDoubleSpinBoxChanged(int i, double value)
{
inputBoxes[i].outputSettings.x = int(x);
}
Second option is to get the spin box index from the sender object
you will have to store it first inside your loop
inputBoxes[i].xSpinBox->setProperty("index",i);
Then you can get it
void MainWindow::setXValue(double d)
{
QDoubleSpinBox * sb = qobject_cast<QDoubleSpinBox *>(QObject::sender());
int iCallerVectorIndex = -1;
if (sb != Q_NULLPTR)
{
iCallerVectorIndex = sb->property("index").toInt(); // to get the caller index.
}
}
If I got you right, in your SLOT method you can call sender() to retrieve the object who emitted the signal. You can compare in a loop the spinBoxes of each of your inputBoxes to find out what caused the SLOT to execute, something like:
// in your SLOT method:
for (int i = 0; i < inputChannels; i++){
if (inputBoxes[i].xSpinBox == (QDoubleSpinBox *)sender()){
// the xSpinBox of the i-th inputBox emitted the signal
break();
}
}
You can also just make myUI a QObject and add slot function there.
You wouldnt need any indexes then.
typedef struct
{
Q_OBJECT
struct{
int x;
int y;
int width;
int height;
int layer;
int idx;
}outputSettings;
QDoubleSpinBox *xSpinBox;
QDoubleSpinBox *ySpinBox;
QDoubleSpinBox *heightSpinBox;
QDoubleSpinBox *widthSpinBox;
QDoubleSpinBox *layerSpinBox;
// Checkboxes
QCheckBox *channelCheckBox;
public slots:
setXValue(double);
setYValue(double);
}myUI;
Example of connect call:
connect(inputBoxes[i].ySpinBox, SIGNAL(valueChanged(double)), inputBoxes[i], SLOT(setYValue(double))
or you can call connect in constructor of myUI:
myUI() {
connect(xSpinBox, SIGNAL(valueChanged(double)),
this, SLOT(setXValue(double))
connect(ySpinBox, SIGNAL(valueChanged(double)),
this, SLOT(setYValue(double))
}
I think that would be much simpler and intuitive because your object is responsible to setting his own members and you dont need to remember any indexes.

How use pointer to access variables of public struct

I have a pointer to a class and I'm trying to use it to access the class' public struct. I've looked at access member var using ptr, as well as access memb struct from ptr class, but when you look at the links, it's not what I'm trying to do.
I'm having trouble doing something that will build. The examples in the code are without pointers, but I have a pointer to IFM to work with. Does anyone know how to use the pointer (to IFM) to access the public struct (in IFM)?
//snippet of code that is trying to access struct in IFM:
const IFM *pJunk = rData1.getM(); //this is fine
pJunk->JunkStruct::Junk.xs; //this doesn't work
The struct in IFM.h:
class IFM final : public IFO
{
public:
typedef struct JunkStruct
{
JunkStruct() = default;
~JunkStruct() = default;
JunkStruct(const IFM::JunkStruct&) = default;
JunkStruct(const double& first, const double& second, const double& third, const double& fourth, const double& fifth, const double& sixth) :
xs(first), ysk(second), xsk(third), ys(fourth), x(fifth), y(sixth)
{}
IFM::JunkStruct& operator=(const IFM::JunkStruct&) = default;
// Initialized
double xs = 1.0;
double ys = 0.0;
double xsk = 0.0;
double ysk = 1.0;
double x = 0.0;
double y = 0.0;
} Junk;
...
OPs member is private. It is designed to be hidden. Nothing to see here.
The struct is just a type. If no members in IFM is of type JunkStruct there is no data there to be accessed. To use that inner type you can see this minimal example
struct Outer
{
struct Inner{
int innerMember;
};
};
int main() {
Outer::Inner inner;
inner.innerMember = 4;
std::cout << inner.innerMember << "\n";
Outer outer;
Outer* outerP = &outer;
outer-> No access to innerMember, it does not exist.
}
If on the other hand, the struct would not be a typedef but just a struct, that definition would be akin to:
struct Outer
{
struct Inner{
int innerMember;
};
Inner outerMemberInner; //
};
int main() {
Outer outer;
Outer* outerP = &outer;
outerP->outerMemberInner.innerMember = 4;
// this might be what you are looking for
std::cout << outerP->outerMemberInner.innerMember;
}
With Junk as outerMemberInner.
The type JunkStruct aliased Junk belongs to the type IFM, not to IFM objects or pointer.

Object::property ( const char * name ) const returning empty QVariant

My class has enum property, i wish to access this property using QObject*. When calling QVariant QObject::property ( const char * name ) const return value is empty QVariant of enum type.
Consider the following code:
/* Interface class */
class IFoo
{
Q_GADGET
public:
Q_ENUMS(ColorType)
typedef enum
{
COLOR_RED = 0,
COLOR_BLUE
} ColorType;
virtual QString Name(void) const = 0;
};
Q_DECLARE_METATYPE(IFoo::ColorType)
class Foo
: public IFoo
{
Q_OBJECT
public:
Foo(void)
{
qint32 typeId = qRegisterMetaType<IFoo::ColorType>("ColorType");
qRegisterMetaTypeStreamOperators<int>(IFoo::ColorType);
}
virtual QString Name(void) const { return _name; }
void SetColor(ColorType color) { _color = color; }
ColorType Color(void) const { return _color; }
QString ColorString(void) const { return _color == IFoo::COLOR_RED ? "Red" : "Blue"; }
Q_PROPERTY(IFoo::ColorType Color READ Color WRITE SetColor)
Q_PROPERTY(QString ColorString READ ColorString)
private:
ColorType _color;
QString _name;
};
int main (int argc, char **argv) {
QCoreApplication app(argc, argv);
Foo f;
f.SetColor(IFoo::COLOR_RED);
qDebug() << f.property("Color"); // Returns QVariant(IFoo::ColorType, )
qDebug() << f.property("ColorString"); // Returns QString(Red)
}
Why does property return empty QVariant value? String wrapper property works as it should.
There were a few mistakes on the code that prevent it from compiling:
Using Q_OBJECT without inheriting from QObject.
qRegisterMetaType is not needed if you use Q_ENUM (which I used to replace Q_ENUMS, which is the old version, deprecated in 5.5).
qRegisterMetaTypeStreamOperators was being passed an int as template argument instead of the type to register, and the argument to the function (not template argument) should be a string, which is optional anyway; but not a type.
Full source:
#include <QtCore> // Just for the test. Use more fine grained includes.
/* Interface class */
class IFoo
{
Q_GADGET
public:
enum ColorType
{
COLOR_RED = 0,
COLOR_BLUE
};
Q_ENUM(ColorType)
virtual QString Name(void) const = 0;
};
class Foo : public QObject, public IFoo
{
Q_OBJECT
public:
Foo(void)
{
qRegisterMetaTypeStreamOperators<IFoo::ColorType>();
}
virtual QString Name(void) const { return _name; }
void SetColor(ColorType color) { _color = color; }
ColorType Color(void) const { return _color; }
QString ColorString(void) const { return _color == IFoo::COLOR_RED ? "Red" : "Blue"; }
Q_PROPERTY(IFoo::ColorType Color READ Color WRITE SetColor)
Q_PROPERTY(QString ColorString READ ColorString)
private:
ColorType _color;
QString _name;
};
int main (int argc, char **argv) {
QCoreApplication app(argc, argv);
Foo f;
f.SetColor(IFoo::COLOR_RED);
qDebug() << f.property("Color"); // Returns QVariant(IFoo::ColorType, )
qDebug() << f.property("ColorString"); // Returns QString(Red)
// Now returns:
// QVariant(IFoo::ColorType, "COLOR_RED")
// QVariant(QString, "Red")
}
#include "main.moc"
It looks like that moc tool is unable to generate strings for respective values. IMO problem is typedef.
Try simple enum inside of class:
enum ColorType {
COLOR_RED = 0,
COLOR_BLUE
};
Or typedef with enum keyword:
typedef enum {
COLOR_RED = 0,
COLOR_BLUE
} ColorType;
I'm pretty sure that missing enum keyword confuses the moc tool.

Resources