C++ calling a vector of classes' method in another class - c++

class C {
public: void c_set(int x){ a = x; }
private: int a;
}
;
class U {
public: void load();
c_loader(int i, int x){ c[i].c_set(x); };
private: vector<C> c(20);
}
;
void U::load() {
int x;
cin >> x >> i;
c_loader(i, x)
}
I'm really confused with this one. I need to call a member function in another one but my problem is that the inside class is a vector of that classes. My code is supposed to work but the result is segfault. Presume that the function cget has definition.

The question is a bit unclear but try this to prevent segfault.
class C {
public: void cget(int a);
private: int a;
};
class U {
public: void load();
vector<C> c; // Note: c is made public in order to add elements from main
};
void U::load(unsigned x, int a) {
if (x < c.size()) // Check the size of c _before_ access
{
c[x].cget(a);
}
}
void main()
{
U u;
C c;
u.c.push_back(c);
u.load(0, 3); // Will end up calling cget
u.load(1, 3); // Will just return without calling cget
}
EDIT:
Just want to mention that the code in the question has changed a lot sinse my answer. That explains why my code looks quite different ;-)
In any case, the answer is still: Check the size of c before accessing it.

Related

C++ : How to ensure that a class member variable is modifiable only within a certain method

I am using C++ 14 with clang on MacOS Sierra. I want to enforce a rule by design. Following is the rule.
I have a member variable in my class say:
unsigned int m_important_num;
There are 4 methods in my class.
fun1();
fun2();
fun3();
fun4();
Objective:
I want only fun2() to be able to change the value of m_important_num.
Question:
Is it possible to make it compiler error if any method other than fun2() changes the variable?
One possible way is to declare it const somehow empower fun2() to change const variables? Is this a good solution? Or are their any better solutions?
Secondary question:
Is it a wrong design to try do such a thing?
Sort of, with additional layer:
class S1 {
public:
void fun2() { /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
unsigned int m_important_num;
};
class S2 : private S1
{
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
As Yakk commented, if func2 need access to S2 members, CRTP can solve that:
template <typename Derived>
class S1 {
public:
void fun2() { asDerived().foo3(); /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
Derived& asDerived() { return stataic_cast<Derived&>(*this); }
private:
unsigned int m_important_num;
};
class S2 : private S1<S2>
{
// friend class S1<S2>; // If required.
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
Encapsulate it down. Put m_important_num in its own class. Aggregate it in your existing class. Have a getter for it. Then put fun2() as a member function of your inner class.
I little variant (if I understand correctly) of the Jeffrey solution: put the variable in an inner class and make it private; create a public getter and make func2() friend to the inner class.
I mean
struct foo
{
int f1 () { return b0.getVal(); }; // you can read `val` everywhere
void f2 () { b0.val = 42; }; // you can write `val` in f2()
void f3 () { /* b0.val = 42; ERROR ! */ }; // but only in f2()
class bar
{
private:
int val = 24;
public:
int getVal () { return val; }
friend void foo::f2 ();
};
bar b0;
};
In other words: friend is your friend.
If you want to prevent a method from modifying any member in the class you can use the trailing const identifier:
class something{
private:
unsigned int var;
public:
void fun1() const;
void fun2();
void fun3() const;
void fun4() const;
}
Here, only fun2() will be able to modify the variable.
I know there are lots of good answers, but there is also an option that you sort of alluded to in your question:
One possible way is to declare it const somehow empower fun2() to change const variables?
#include <iostream>
using uint = unsigned int;
class Test
{
const uint num;
public:
Test(uint _num)
:
num(_num)
{}
uint get_num() const
{
return num;
}
void can_change_num(uint _new_num)
{
uint& n(const_cast<uint&>(num));
n = _new_num;
}
void cant_change_num(uint _new_num)
{
// num = _new_num; // Doesn't compile
}
};
int main()
{
Test t(1);
std::cout << "Num is " << t.get_num() << "\n";
t.can_change_num(10);
std::cout << "Num is " << t.get_num() << "\n";
return 0;
}
Produces
Num is 1
Num is 10
You already got lots of good answers to your primary question. I'll try to address the secondary one.
Is it a wrong design to try do such a thing?
It's hard to say w/o knowing more about your design. In general anything like this detected during a code review would raise a big red flag. Such a protection makes sense in a case of a big class with convoluted logic/implementation. Otherwise why would you like to go an extra mile and make your code much more complicated? The fact you seek for this can indicate your class became unmanageable.
I'd recommend to consider splitting it to smaller parts with better defined logic where you won't worry such mistakes can happen easily.

Initialization of anonymous class member variable with std::function

I wonder if there is a workaround is such situation:
class A
{
class
{
public:
void setValue(int val) {i=val;}
private:
int i;
} B = initB(10);
std::function<decltype(B)(int)> initB = [this](int value)
{decltype(B) temp;
temp.setValue(value);
return temp;};
}
//...
A a; //crash
//...
I suppose it is caused by order of initialization. Variable B is initilized by calling an uninitilized std::function instance, hence the crash. By my logic, the workaround would be to initialize std::function first, then initialize member B. But then, such code is not valid:
class A
{
//error: 'B' was not declared in this scope
std::function<decltype(B)(int)> initB = [this](int value)
{decltype(B) temp;
temp.setValue(value);
return temp;};
class
{
public:
void setValue(int val) {i=val;}
private:
int i;
} B = initB(10);
}
I tried to make to make the std::function static, and such code works, but requires non-constexpr/const member, because std::function has non-trivial destructor - which is bad, because that requires source file, which requires creating such file, which requires some efford and destruction of my beautiful header-only class hierarchy! (I mean, I could be lazy and define this variable in the header, but then the multiple definition problem occurs). I know it might be a bad design (i'm just testing things out), but do you have any ideas how the problem can be solved without involving source files?
Although your example is contrived, there are times when I've needed (or its more convenient) to initialize complex objects in a similar way.
But, why use std::function<>? Why not just use a function?
class A
{
class
{
public:
void setValue(int val) { i = val; }
private:
int i;
} B = initB(10);
static decltype(B) initB(int value)
{
decltype(B) temp;
temp.setValue(value);
return temp;
}
};
Although, I wouldn't normally use decltype(B); I would just give the class a name.
I feel like I am somehow subverting your intent, but if you initialize the variables in the constructor, you can make things work.
#include <functional>
class A
{
class
{
public:
void setValue(int val) {i=val;}
private:
int i;
} B;
std::function<decltype(B)(int)> initB;
public:
A() {
initB = [this](int value)
{decltype(B) temp;
temp.setValue(value);
return temp;};
B = initB(10);
}
};
int main() {
A a;
}
A::initB is a value. It's not initialized at the point where you call it, because initialization is done (loosely speaking) in the order you specify member fields. You can verify this by executing the below, which works:
#include <iostream>
#include <functional>
using namespace std;
template<typename T, typename U>
T set(T& tgt, const U& src)
{
new(&tgt) T(src);
return tgt;
}
class A
{
class
{
public:
void setValue(int val) {i=val;}
private:
int i;
} B = set(initB, [this](int value)
{decltype(B) temp;
temp.setValue(value);
return temp;})(10);
std::function<decltype(B)(int)> initB;
};
int main() {
A a;
}

How not to repeat myself without macros when writing similar CUDA kernels?

I have several CUDA Kernels which are basically doing the same with some variations. What I would like to do is to reduce the amout of code needed. My first thought was to use macros, so my resulting kernels would look like this (simplified):
__global__ void kernelA( ... )
{
INIT(); // macro to initialize variables
// do specific stuff for kernelA
b = a + c;
END(); // macro to write back the result
}
__global__ void kernelB( ... )
{
INIT(); // macro to initialize variables
// do specific stuff for kernelB
b = a - c;
END(); // macro to write back the result
}
...
Since macros are nasty, ugly and evil I am looking for a better and cleaner way. Any suggestions?
(A switch statement would not do the job: In reality, the parts which are the same and the parts which are kernel specific are pretty interweaved. Several switch statements would be needed which would make the code pretty unreadable. Furthermore, function calls would not initialize the needed variables. )
(This question might be answerable for general C++ as well, just replace all 'CUDA kernel' with 'function' and remove '__global__' )
Updated: I was told in the comments, that classes and inheritance don't mix well with CUDA. Therefore only the first part of the answer applies to CUDA, while the others are answer to the more general C++ part of your question.
For CUDA, you will have to use pure functions, "C-style":
struct KernelVars {
int a;
int b;
int c;
};
__device__ void init(KernelVars& vars) {
INIT(); //whatever the actual code is
}
__device__ void end(KernelVars& vars) {
END(); //whatever the actual code is
}
__global__ void KernelA(...) {
KernelVars vars;
init(vars);
b = a + c;
end(vars);
}
This is the answer for general C++, where you would use OOP techniques like constructors and destructors (they are perfectly suited for those init/end pairs), or the template method pattern which can be used with other languages as well:
Using ctor/dtor and templates, "C++ Style":
class KernelBase {
protected:
int a, b, c;
public:
KernelBase() {
INIT(); //replace by the contents of that macro
}
~KernelBase() {
END(); //replace by the contents of that macro
}
virtual void run() = 0;
};
struct KernelAdd : KernelBase {
void run() { b = a + c; }
};
struct KernelSub : KernelBase {
void run() { b = a - c; }
};
template<class K>
void kernel(...)
{
K k;
k.run();
}
void kernelA( ... ) { kernel<KernelAdd>(); }
Using template method pattern, general "OOP style"
class KernelBase {
virtual void do_run() = 0;
protected:
int a, b, c;
public:
void run() { //the template method
INIT();
do_run();
END();
}
};
struct KernelAdd : KernelBase {
void do_run() { b = a + c; }
};
struct KernelSub : KernelBase {
void do_run() { b = a - c; }
};
void kernelA(...)
{
KernelAdd k;
k.run();
}
You can use device functions as "INIT()" and "END()" alternative.
__device__ int init()
{
return threadIdx.x + blockIdx.x * blockDim.x;
}
Another alternative is to use function templates:
#define ADD 1
#define SUB 2
template <int __op__> __global__ void caluclate(float* a, float* b, float* c)
{
// init code ...
switch (__op__)
{
case ADD:
c[id] = a[id] + b[id];
break;
case SUB:
c[id] = a[id] - b[id];
break;
}
// end code ...
}
and invoke them using:
calcualte<ADD><<<...>>>(a, b, c);
The CUDA compiler does the work, build the different function versions and removes the dead code parts for performance optimization.

C++ Pointer to Object as Class member

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();}

Accessing/filling a vector from a different class?

I am confused on how to fill a vector with values from a different class.
Can anyone give me a coded example how this is done. :)
Class A
{
//vector is here
}
Class B
{
//add values to the vector here
}
main()
{
//access the vector here, and print out the values
}
I appreciate the help <3
It seems like a quick lesson in access levels and encapsulation is in order.
My guess, based on the questions touch is that you're looking for the following code.
int main()
{
ClassA[] as = {new ClassA(), new ClassA(), ... }
ClassB[] bs = {new ClassB(), new ClassB(), ... }
}
But I'm shooting in the dark, a bit. :)
You should make your question more specific, edit it and post what you've tried to do. If you mean to do something respecting oop-rules, the play looks like this:
#include<iostream>
#include<vector>
class A{
public:
void fill_up_the_vector() { v=std::vector<int>(3); v[0]=0; v[1]=1; v[2]=4; }
void add( a.add(i); ) { v.push_back(i); }
void display_last() const { std::cout<<v[v.size()-1]; }
private:
std::vector<int> v;
};
class B{
public:
B(){ a.fill_up_the_vector(); } // B just *instructs* A to fill up its vector.
void add_value(int i) { a.add(i); }
void display() const { a.display_last(); }
private:
A a;
};
int main()
{
B b;
b.add_value(9);
b.display(); // reads v through A.
}
Note that this example above is a bit different from what you've asked. I posted it since I think you sould keep in mind that according to OOP rules
you don't want to access values in A directly,
B should have a member with type A if you plan to access a value in A,
you're supposed to access a value in A through B if you have filled it up from B.
The other way to go is not OOP:
struct A{
std::vector<int> v;
};
struct B{
static void fill_A(A& a) const { a.v = std::vector<int>(3); a.v[0]=0; a.v[1]=1; a.v[2]=4; }
};
int main()
{
A a;
B::fill_A(a);
a.v.push_back(9);
std::cout << a.v[a.v.size()-1];
}
but this code is as horrible as it gets.