I'm having a little problem setting values in my private struct of my Class. It is like the following:
//ProcessImage.h
class Process_Image
{
private:
struct ImageData
{
Mat imageMatrix;
int V_Min;
int V_Max;
Imagedata(Mat img, int Vmin=0, int Vmax=255):
imageMatrix(img), V_Min(Vmin), V_Max(Vmax) {}
};
public:
bool set_V_Min(int Value);
};
//ProcessImage.cpp
bool Process_Image::set_V_Min(int Value)
{
if(value>0&&value<256)
{
ImageData.V_Min=value; //it is not working setting it like this
return true;
}
return false;
}
Where am I wrong? I think it should be possible to set the value in my struct that way but I don't know what I'm missing. Please give me a hint or a direction how to do it the right Way.
You haven't created the structure yet, only described it. To have constant structure inside class write it down like this:
class Process_Image
{
private:
struct ImageData
{
Mat imageMatrix;
int V_Min;
int V_Max;
Imagedata(Mat img, int Vmin=0, int Vmax=255):
imageMatrix(img), V_Min(Vmin), V_Max(Vmax) {}
}ImageData; // <- your missing part
public:
bool set_V_Min(int Value);
};
Related
I have a nested class called cell in my main class something.
I c
class Something{
class Cell
{
public:
int get_row_Number();
void set_row_Number(int set);
char get_position_Letter();
static void set_position_Letter(char set);
void set_whohasit(char set);
char get_whohasit();
Cell(int row,char letter,char whohasit);
private:
char position_Letter;
int row_Number;
char whohasit;
};
};
I wanna implement nested class constructor in .cpp file
Something::Cell Cell(int row,char letter,char whohasit){
Something::Cell::set_position_Letter(letter);
Something::Cell::set_row_Number(row);
Something::Cell::set_whohasit(whohasit);
}
But it is wrong. I assumed correct would be Something::Cell::Something::Cell at first but i don't think thats true either.
You are almost there. It's as simple as:
Something::Cell::Cell(int row,char letter,char whohasit){
Something::Cell::set_position_Letter(letter);
Something::Cell::set_row_Number(row);
Something::Cell::set_whohasit(whohasit);
}
But actually, I would strongly recommend you use initializers, rather than constructing the members uninitialized, and then assigning to them:
Something::Cell::Cell(int row, char letter, char whohasit)
:position_Letter(letter)
,row_Number(row)
,whohasit(whohasit)
{}
You need to make your inner class public, and the method set_Position_Letter cannot be static, because char position_Letter is not static (here is the header):
class Something
{
public:
class Cell {
public:
int get_row_Number();
void set_row_Number(int set);
char get_position_Letter();
void set_position_Letter(char set);
void set_whohasit(char set);
char get_whohasit();
Cell(int row,char letter,char whohasit);
private:
char position_Letter;
int row_Number;
char whohasit;
};
};
This is the cpp:
Something::Cell::Cell(int row, char letter, char whohasit) {
set_position_Letter(letter);
set_row_Number(row);
set_whohasit(whohasit);
}
void Something::Cell::set_position_Letter(char set) {
this->position_Letter = set;
}
void Something::Cell::set_whohasit(char set) {
this->whohasit = set;
}
void Something::Cell::set_row_Number(int set) {
this->row_Number = set;
}
I've been banging my head for quite some time now trying to create an array/vector that can contain references to several types of variables, see the example:
class Validate
{
private:
some_array/vector[]; //0 would refer to x, 1 to y, and so on..
uint8_t x;
uint16_t y;
int32_t z;
public:
Validate();
void doSomething(uint8_t &member);
void doSomething(uint16_t &member);
void doSomething(int32_t &member);
}
The whole point is so that I can use this array/vector easily in a "for loop", something like this:
void Validate::doSomething(uint_8 &member)
{
//Do whatever with the variable refered to.
}
Validate::Validate()
{
for(int i = 0 ; i < 2 ; i++)
doSomething(some_array/vector[i]);
}
Perhaps somebody have an answer or possibly a better solution for me.
You have two problems. Firstly, a container cannot contain elements of different types. Secondly, you cannot store references in a container.
One way of solving the first problem is to use std::variant from C++17 (or boost::variant). To solve the second problem you could use std::reference_wrapper:
class Validate {
using Uint8Ref = std::reference_wrapper<uint8_t>;
using Uint16Ref = std::reference_wrapper<uint16_t>;
using Uint32Ref = std::reference_wrapper<int32_t>;
using MemberType = std::variant<Uint8Ref, Uint16Ref, Uint32Ref>;
std::vector<MemberType> members;
uint8_t x;
uint16_t y;
int32_t z;
public:
Validate();
void doSomething(uint8_t &member);
void doSomething(uint16_t &member);
void doSomething(int32_t &member);
};
Validate::Validate() : members({std::ref(x), std::ref(y), std::ref(z)}) {
for (auto member : members) {
std::visit([this](auto member){this->doSomething(member);}, member);
}
}
Live demo.
Alternatively, you could create a polymophic base class for a member that you can store in a container:
class MemberType {
public:
virtual ~MemberType(){}
virtual void accept(Validate& validate) = 0;
};
class Validate {
std::array<std::unique_ptr<MemberType>, 3> members;
// as before...
};
template<typename T>
class MemberTypeImpl : public MemberType {
T& member;
public:
MemberTypeImpl(T& member) : member(member){}
void accept(Validate& validate) override {
validate.doSomething(member);
}
};
template<typename T>
std::unique_ptr<MemberType> make_member_type(T& member) {
return std::make_unique<MemberTypeImpl<T>>(member);
}
Validate::Validate()
: members({make_member_type(x), make_member_type(y), make_member_type(z)}) {
for (auto& member : members) {
member->accept(*this);
}
}
I defined a class in the header file like this:
class myClass
{
public:
void test();
void train();
private:
bool check;
}
Then in the cpp file, I did this:
void myClass::test()
{
int count = 9;
//some other work
}
void myClass::train()
{
int newValue = count;
....
}
Then without surprise, I got an error saying count is not defined. So what I want to do is in my train function use the count value that is defined in the test. Is there any good way to do this without using any additional dependencies? Thank you.
Well yes. That's called a member variable. Exactly like your bool check;.
Do
private:
bool check;
int count;
and then use it directly in your functions.
void myClass::test()
{
count = 9;
//Same as this->count = 9;
}
void myClass::train()
{
int newValue = count;
//Same as int newValue = this->count;
}
In your example, when method test finishes its work, count variable does not exist anymore, so there's no way of accessing it. You have to ensure, that its lifetime will be long enough to be accessed from another place. Making it a class field solves the problem (this is what class fields are for :)).
Do it this way:
class myClass
{
public:
void test();
void train();
private:
bool check;
int count; // <- here
}
and then
void myClass::test()
{
count = 9;
//some other work
}
But that's not the only solution. You can do it in another way, say:
class myClass
{
public:
int test()
{
// do some work
return 9;
}
void train(int count)
{
int newValue = count;
}
}
// (somewhere)
myClass c;
int count = c.test();
c.train(count);
That all depends on what test, train and count are for...
I'm trying to get two different classes to interact with eachother, for that I have in one class a pointer to an object of an other class, which is specified in the constructor.
Interaction works so far, I can change the paramters of the pointed-to object and I can see the changes, as I'm printing it on a terminal. BUT when I try to get a parameter from this object and try to print it to the terminal through the class which points to it I only get a zero value for an Int from which I know, cause of debug outputs, that it isn't zero, if called directly.
I will give you an example of the code:
Class A:
class Spieler
{
private:
int score;
Schlaeger *schlaeger;
int adc_wert;
int channel;
public:
Spieler(int x, Schlaeger &schl, int adc_wert_c=0, int channel_c=0 )
{
score=x;
schlaeger=&schl;
adc_wert=adc_wert_c;
channel=channel_c;
}
//....
void set_schl(Schlaeger &schl){ schlaeger=&schl;}
int getPosY(){ schlaeger->getSchlaeger_pos_y();}
int getPosX(){ schlaeger->getSchlaeger_pos_x();}
void setPosY(int y){ schlaeger->set_pos_y(y);}
void schlaeger_zeichen(){
schlaeger->schlaeger_zeichen();
}
void schlaeger_bewegen(){
schlaeger->schlaeger_bewegen(getADC());
}
//...
};
Class B:
class Schlaeger
{
private:
int schlaeger_pos_x;
int schlaeger_hoehe;
int schlaeger_pos_y;
public:
Schlaeger(int x=0, int h=5, int pos_y=15)
{
schlaeger_pos_x=x;
schlaeger_hoehe=h;
schlaeger_pos_y=pos_y;
}
int getSchlaeger_pos_x()
{
return schlaeger_pos_x;
}
int getSchlaeger_pos_y()
{
return schlaeger_pos_y;
}
int getSchlaeger_hoehe()
{
return schlaeger_hoehe;
}
void set_pos_y(int new_y)
{
schlaeger_pos_y=new_y;
}
};
The calls to the changing methods work, I can see the changes and I can see it in a debug output.
You're not returning the value in the getter
int getPosY(){ schlaeger->getSchlaeger_pos_y();}
should be
int getPosY(){ return schlaeger->getSchlaeger_pos_y();}
I've got a struct "margin" in my class with 4 properties. Instead of writing four different getter/setter methods, I figured I could do it in a better way:
class myClass {
private:
struct margin {
int bottom;
int left;
int right;
int top;
}
public:
struct getMargin();
void setMargin(string which, int value);
};
But how can I set the property of the struct corresponding with the string "which" from within the function setMargin()? For example, if I call myClass::setMargin("left", 3), how can I then set "margin.left" to "3"? Preferably while keeping the struct POD? I really can't figure this out...
And on a side note, is this really better than writing many getter/setter methods?
Thanks!
First, your idea is terrible... :)
Note you don't even have a margin member (added below)
I'd use an enum for this, if you don't want setters/getters for each property:
class myClass {
private:
struct margin {
int bottom;
int left;
int right;
int top;
} m; // <--- note member variable
public:
enum Side
{
bottom, left, rigth, top
};
struct getMargin();
void setMargin(Side which, int value);
};
and have a switch statement inside setMargin.
void myClass::setMargin(Side which, int value)
{
switch (which)
{
case bottom:
m.bottom = value;
break;
//....
}
}
class myClass {
private:
int margin[4];
public:
enum Side
{
bottom, left, rigth, top
};
void setMargin(Side which, int value);
};
void myClass::setMargin(Side which, int value)
{
margin[which]=value;
}
Either Luchian's or Gir's suggestion would be my preference. If you really want need a look up by a string, though, it is probably best to do that with an associative container.
class MyClass {
std::map<std::string, int> m_;
public:
bool setMargin(std::string which, int value) {
std::map<std::string, int>::iterator i = m_.find(which);
if (i == m_.end()) return false;
i->second = value;
return true;
}
};
This is only useful if you have a dynamic interface that allows your user to define their own margins by name.
If you can make margin public, you can get rid of get,set methods:
class myClass {
public:
struct Margin {
int bottom;
int left;
int right;
int top;
};
Margin margin;
};
myClass mc;
mc.margin.bottom = mc.margin.left;
You can use "relative pointer" which points the distance from the address of struct to point a special element. For example:
SetMargin(FIRST,5);
Which FIRST is from an enum value and is 0.
SetMargin(SECOND,100);
SECOND is 4 since int is 4 bytes in my system
implementation:
void SetMargin(enum margin_elements,int a)
{
int *relative=struct_pointer+(int*)margin_elements;
*relative_pointer=a;
return;
}