Getting one private member from one class to another - c++

So, I have an algorithm that takes a few sensors, scales them to a temperature and puts the temps in a global data store. However, sensor class A does more calculations that Class B needs. I can't put the new calcs in the data store, and i don't want to include class A inside class B just to get one piece of data with a getter.
Class A
{
private:
float x[4];
float y[4];
public:
//Scaling functions, etc...
}
Class B
{
private:
float c[4];
public:
//Scaling functions etc...
}
What would be the best way to get x[4] passed to class B to put in c[4]? The real classes have much more going on, this is about as simple as I think I can make. x[4] has data that needs to be used in class B.

class A
{
private:
float x[4];
float y[4];
public:
float* getXs()
{
return x;
}
}
class B
{
private:
float c[4];
public:
//Scaling functions etc...
void setXs(float *x)
{
for (int i=0;i<4;i++)
c[i] = x[i];
}
}

Well, you could use friends, if you're not willing to write accessors:
http://en.wikipedia.org/wiki/Friend_class
Some would argue this breaks encapsulation, and that a getter would be the preferred approach.

Use a getter of x[4] on an instance of A when calling the constructor of B.
#include <string.h>
class A
{
private:
float x[4];
float y[4];
public:
float const *xArray() const
{
return x;
}
};
class B
{
private:
float c[4];
public:
void setCArray(float const arr[4])
{
memcpy(c, arr, 4 * sizeof(int));
}
};
int main()
{
A a;
B b;
b.setCArray(a.xArray());
}

There are number of ways. The best depends on Your criteria.
If time is not crucial for you I would be simple and use copy constructor:
Class A
{
private:
float x[4];
float y[4];
public:
const float& X(int i) { return x[i]; }
}
Class B
{
private:
float c[4];
public:
B( const A& a ) {
for( k = 0; k < 4; k++ )
c[k] = a.X(k);
}
}
If time is crucial you can consider to use pointers copy. But be Very accurate with it:
Class A
{
private:
friend B;
float x[4];
float y[4];
public:
...
}
Class B
{
private:
const float* const c;
public:
B( const A& a ):c(a.x){}
// use c like c[4], but don't change it.
}

Related

class inheritance and using setters and getters

Here I've made a derived class called Essay, from the base class GradedActivity. I've made an object of the Essay class in main called object. When I wrote object.setGrammar(grammarPts) in main(), I'd hoped to feed what the score is to be held in the variable grammar in the setGrammar() function. What am I doing wrong? Thanks!
I get one error:
99 8 F:\lab6part3.cpp [Error] request for member 'setGrammar' in 'object', which is of non-class type 'Essay(float, float, float, float)'
#include <iostream>
using namespace std;
//class gradedactivity (page 900)
class GradedActivity
{
protected:
double score;
public:
//default constructor
GradedActivity()
{
score = 0.0;
}
//parameterized constructor
GradedActivity(double s)
{
score = s;
}
setScore(double s)
{
score = s;
}
double getScore() const
{
return score;
}
char getLetterGrade() const;
};
class Essay : public GradedActivity
{
private:
float grammar;
float spelling;
float length;
float content;
public:
Essay(float g, float s, float l, float c)
{
setGrammar(g);
setSpelling(s);
setLength(l);
setContent(c);
}
void setGrammar(float);
float getGrammar();
void setSpelling(float);
float getSpelling();
void setLength(float);
float getLength();
void setContent(float);
float getContent();
};
void Essay::setGrammar(float g)
{
grammar = g;
}
float Essay::getGrammar() {return grammar;}
void Essay::setSpelling(float s)
{
spelling = s;
}
float Essay::getSpelling() {return spelling;}
void Essay::setLength(float l)
{
length = l;
}
float Essay::getLength() {return length;}
void Essay::setContent(float c)
{
content = c;
}
float Essay::getContent() {return content;}
int main()
{
float grammarPts;
cout << "How many points, out of 30, did the student get for grammar?";
cin >> grammarPts;
Essay object;
object.setGrammar(grammarPts);
return 0;
}
This could just be because you never defined a default constructor for Essay.
Anyway, I defined a default constructor and your code runs fine so that might be the issue. https://ideone.com/yNxV8N

Constructors accessing private data

Still new to C++ and I'm trying to understand accessing private data, using constructors. How would I display the values of the data members of myClass? Any help would be great. Thanks
class NumberClass
{
public:
void func(); // assigns numeric constants to nNum and fNum
void print() const; //displays the values of nNum and fNum
NumberClass();
NumberClass(int, float);
private:
int nNum;
float fNum;
};
int main()
{
NumberClass myClass;
//display values here
return 0;
}
By the looks of your interface, your professor probably wants you to implement print() to print the members, and then call that method on your object.
You could implement print(), and call it with a instance of NumberClass. Like
NumberClass obj;
...
obj.print()
You could write get methods for the class which is a good way to print it.
class NumberClass
{
public:
void func(); // assigns numeric constants to nNum and fNum
void print() const; //displays the values of nNum and fNum
NumberClass();
NumberClass(int, float);
private:
int nNum;
float fNum;
public int getNum(){
return nNum;
}
public float getNum(){
return fNum;
}
};
int main()
{
NumberClass myClass;
//display values here
cout<<myClass.getNum();
return 0;
}
Could be the example but I didint checked so you can fixed the little issues.

Declaring readonly variables on a C++ class or struct

I'm coming to C++ from C# and const-correctness is still new to me. In C# I could declare a property like this:
class Type
{
public readonly int x;
public Type(int y)
{
x = y;
}
}
This would ensure that x was only set during initialization. I would like to do something similar in C++. The best I can come up with though is:
class Type
{
private:
int _x;
public:
Type(int y) { _x = y; }
int get_x() { return _x; }
};
Is there a better way to do this? Even better: Can I do this with a struct? The type I have in mind is really just a collection of data, with no logic, so a struct would be better if I could guarantee that its values are set only during initialization.
There is a const modifier:
class Type
{
private:
const int _x;
int j;
public:
Type(int y):_x(y) { j = 5; }
int get_x() { return _x; }
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Note that you need to initialize constant in the constructor initialization list. Other variables you can also initialize in the constructor body.
About your second question, yes, you can do something like this:
struct Type
{
const int x;
const int y;
Type(int vx, int vy): x(vx), y(vy){}
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Rather than a collection of constants, you could have a constant collection. The property of being constant seems to pertain to your use case, not the data model itself. Like so:
struct extent { int width; int height; };
const extent e { 20, 30 };
It's possible to have specifically constant data members of a class, but then you need to write a constructor to initialize it:
struct Foo
{
const int x;
int & y;
int z;
Foo(int a, int & b) : x(a + b), y(b), z(b - a) { }
};
(The example also shows another type of data member that needs to be initialized: references.)
Of course, structs and classes are the same thing.
You can initialize class const members with constructor. If you need add some other logic in constructor, but in .cpp file not in .h, you can create a private method and call it in constructor.
File.h
class Example
{
private:
const int constantMember1;
const int constantMember2;
const int constantMember3;
void Init();
public:
Example(int a, int b) :constantMember1(a), constantMember2(b), constantMember3(a + b) {
//Initialization
Init();
};
};
File.cpp
void Init()
{
//Some Logic intialization
}
This is not exactly answering the question asked, but if you wanted to have the simplicity of directly accessing member variables in a struct without getters, but wanted to ensure that nobody could modify the values, you could do something like this:
#include <iostream>
using namespace std;
class TypeFriend;
struct Type
{
const int &x;
const int y;
Type (int vx, int vy):x (_x), y (vy), _x (vx)
{
}
private:
friend class TypeFriend;
int _x;
};
struct TypeFriend
{
TypeFriend (Type & t):_t (t)
{
}
void setX (int newX)
{
_t._x = newX;
}
private:
Type & _t;
};
int main ()
{
Type t (1, 2);
TypeFriend tf (t);
cout << t.x << "," << t.y << endl;
// t.x = 6; // error: assignment of read-only location ‘t.Type::x’
// cout<<t.x << ","<<t.y<<endl;
tf.setX (5);
cout << t.x << "," << t.y << endl;
return 0;
}
The result of running this is:
1,2
5,2
Type::x cannot be modified externally, so it is read-only, but via TypeFriend it can be changed. This can be useful if you wanted to expose a simple interface of direct member access for reading, but wanted to restrict how those members could be changed.

Making a structure in class

I am making my first steps in learning OOP . And here is the first problem which I can't solve.
The max function in this class should return the maximum of two numbers . I want to keep the numbers in the private scope and the functions in the public scope . But when I want to use variables from struct data{} in the public scope the compiler says that the variables are not declared . Please tell me why I get these errors .
class myclass{
private:
struct data{
int q ;
int w;
};
public:
void get(int a, int b){
struct data = {a , b}; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(q>w)
return q;
else
return w;
}
};
struct data{
int q ;
int w;
};
only declares a type, not an object, so there are no q and w members anywhere inside your class instances. You need the declare an instance of the struct:
struct {
int q;
int w;
} data;
Then, you can write max as:
int max()
{
if (data.q > data.w)
return data.q;
else
return data.w;
}
(I've no idea what your get method is supposed to do, so I have no replacement for that.)
In C++ "class" and "struct" are close to being synonymous (the same thing). The ONLY difference is that a "struct" defaults to being "public" accessibility while a "class" defaults to private.
Once you understand this, it should become obvious that what you are doing is defining a sub-type within your class.
class myclass {
private: // <- not required, you already said that by saying "class".
struct data {
// <-- this is a class definition with "public:" just here.
...
};
};
C++ allows you to nest class/structure definitions so that you can, for example, create structures that marshal parameters or return values.
class Database {
class Result { ... };
};
...
class Exam {
class Result { ... };
};
These two result classes avoid namespace collision, by being Database::Result and Exam::Result instead of just "Result".
However - these are only definitions. They do not - as shown - have any effect on the outlying class, that is: they aren't being used to add a member to the class.
Your code:
class myclass{
private:
struct data{ // <-- this is a TYPE declaration, struct myclass::data
int q ; //
int w; //
}; // <-- no member name here so does not affect myclass itself.
public:
void get(int a, int b){
struct data = {a , b}; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(q>w)
return q;
else
return w;
}
};
Declares a type "myclass::data" but does not add a member of type "myclass::data" to the class. The line "struct data = " is illegal, you're trying to assign values to a TYPE.
It should probably be written as
class MyClass {
int m_q;
int m_w;
public:
void set(int q, int w) {
m_q = q;
m_w = w;
}
int max() const {
return (m_q > m_w) ? m_q : m_w;
// or #include <algorithm> and return std::max(m_q, m_w);
}
};
You only need to hoist q & w into a struct if you are going to reuse that structural definition outside the confines of the class, e.g. in derived or parallel classes where you may want to add more of the same type of thing, in which case, you could perhaps do the following, but if you do it this exact way you'll eventually kick yourself for breaking encapsulation:
class MyClass {
public:
struct Data {
int m_q;
int m_w;
};
private:
Data m_data;
void set(int q, int w) {
m_data.m_q = q;
m_data.m_w = w;
}
int max() const {
return (m_data.m_q > m_data.m_w) ? m_data.m_q : m_data.m_w;
}
};
A better way, if this coupling of members needs to be externally visible to some degree would be:
class MyClass {
public:
class Data {
int m_q;
int m_w;
public:
Data() : m_q(0), m_w(0) {}
Data(int q, int w) : m_q(0), m_w(0) {}
void set(int q, int w) {
m_q = w;
m_w = w;
}
int q() const { return m_q; }
int w() const { return m_w; }
int max() const { return (m_q > m_w) ? m_q : m_w;
};
private:
Data m_data;
public:
MyClass() : m_data() {} // or = default
MyClass(int q, int w) : m_data(q, w) {}
MyClass(const Data& data) : m_data(data) {}
// Read-only access
const Data& data() const { return m_data; }
// To allow write access, e.g. for set:
Data& data() { return m_data; }
};
It's kinda overkill for such a simple case, but welcome to C++: the boilerplate language.
You have defined the structure but there is no object of that type. You should declare an object and you will not get any error.
class myclass{
private:
struct data{
int q ;
int w;
}var;
public:
void get(int a, int b){
var .q= a;
var.w=b; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(var.q>var.w)
return var.q;
else
return var.w;
}
};

"Retroactive Union" - can it be done?

I've got two classes: a template class, and a regular class that inherits from it:
template <int N> class Vector
{
float data[N];
//etc. (math, mostly)
};
class Vector3 : public Vector<3>
{
//Vector3-specific stuff, like the cross product
};
Now, I'd like to have x/y/z member variables in the child class (full members, not just getters - I want to be able to set them as well). But to make sure that all the (inherited) math works out, x would have to refer to the same memory as data[0], y to data[1], etc. Essentially, I want a union, but I can't declare one in the base class because I don't know the number of floats in the vector at that point.
So - can this be done? Is there some sort of preprocessor / typedef / template magic that will achieve what I'm looking for?
PS: I'm using g++ 4.6.0 with -std=c++0x, if that helps.
Edit: While references would give the syntax I'm looking for, the ideal solution wouldn't make the class any bigger (And references do - a lot! A Vector<3> is 12 bytes. A Vector3 with references is 40!).
How about:
class Vector3 : public Vector<3>
{
public:
// initialize the references...
Vector3() : x(data[0]), y(data[1]), z(data[2]){}
private:
float& x;
float& y;
float& z;
};
Of course, if you want them to occupy the same space, then that's a different story...
With a little template magic, you can do the following...
#include <iostream>
template <int N, typename UnionType = void*> struct Vector
{
union
{
float data[N];
UnionType field;
};
void set(int i, float f)
{
data[i] = f;
}
// in here, now work with data
void print()
{
for(int i = 0; i < N; ++i)
std::cout << i << ":" << data[i] << std::endl;
}
};
// Define a structure of three floats
struct Float3
{
float x;
float y;
float z;
};
struct Vector3 : public Vector<3, Float3>
{
};
int main(void)
{
Vector<2> v1;
v1.set(0, 0.1);
v1.set(1, 0.2);
v1.print();
Vector3 v2;
v2.field.x = 0.2;
v2.field.y = 0.3;
v2.field.z = 0.4;
v2.print();
}
EDIT: Having read the comment, I realise what I posted before was really no different, so a slight tweak to the previous iteration to provide direct access to the field (which is what I guess you are after) - I guess the difference between this and Rob's solution below is that you don't need all the specializations to implement all the logic again and again...
How about template specialization?
template <int N> class Vector
{
public:
float data[N];
};
template <>
class Vector<1>
{
public:
union {
float data[1];
struct {
float x;
};
};
};
template <>
class Vector<2>
{
public:
union {
float data[2];
struct {
float x, y;
};
};
};
template <>
class Vector<3>
{
public:
union {
float data[3];
struct {
float x, y, z;
};
};
};
class Vector3 : public Vector<3>
{
};
int main() {
Vector3 v3;
v3.x;
v3.data[1];
};
EDIT Okay, here is a different approach, but it introduces an extra identifier.
template <int N> class Data
{
public:
float data[N];
};
template <> class Data<3>
{
public:
union {
float data[3];
struct {
float x, y, z;
};
};
};
template <int N> class Vector
{
public:
Data<N> data;
float sum() { }
float average() {}
float mean() {}
};
class Vector3 : public Vector<3>
{
};
int main() {
Vector3 v3;
v3.data.x = 0; // Note the extra "data".
v3.data.y = v3.data.data[0];
};
Here's one possibility, cribbed from my answer to this question:
class Vector3 : public Vector<3>
{
public:
float &x, &y, &z;
Vector3() : x(data[0]), y(data[1]), z(data[2]) { }
};
This has some problems, like requiring you to define your own copy constructor, assignment operator etc.
You can make the following:
template <int N> struct Vector
{
float data[N];
//etc. (math, mostly)
};
struct Vector3_n : Vector<3>
{
//Vector3-specific stuff, like the cross product
};
struct Vector3_a
{
float x, y, z;
};
union Vector3
{
Vector3_n n;
Vector3_a a;
};
Now:
Vector3 v;
v.n.CrossWhatEver();
std::cout << v.a.x << v.a.y << v.a.z
You could try the anonymous union trick, but that is not standard nor very portable.
But note that with this kind of union it is just too easy to fall into undefined behaviour without even noticing. It will probably mostly work anyway, though.
I wrote a way a while back (that also allowed getters/setters), but it was such a non-portable garrish hack that YOU REALLY SHOULD NOT DO THIS. But, I thought I'd throw it out anyway. Basically, it uses a special type with 0 data for each member. Then, that type's member functions grab the this pointer, calculate the position of the parent Vector3, and then use the Vector3s members to access the data. This hack works more or less like a reference, but takes no additional memory, has no reseating issues, and I'm pretty sure this is undefined behavior, so it can cause nasal demons.
class Vector3 : public Vector<3>
{
public:
struct xwrap {
operator float() const;
float& operator=(float b);
float& operator=(const xwrap) {}
}x;
struct ywrap {
operator float() const;
float& operator=(float b);
float& operator=(const ywrap) {}
}y;
struct zwrap {
operator float() const;
float& operator=(float b);
float& operator=(const zwrap) {}
}z;
//Vector3-specific stuff, like the cross product
};
#define parent(member) \
(*reinterpret_cast<Vector3*>(size_t(this)-offsetof(Vector3,member)))
Vector3::xwrap::operator float() const {
return parent(x)[0];
}
float& Vector3::xwrap::operator=(float b) {
return parent(x)[0] = b;
}
Vector3::ywrap::operator float() const {
return parent(y)[1];
}
float& Vector3::ywrap::operator=(float b) {
return parent(y)[1] = b;
}
Vector3::zwrap::operator float() const {
return parent(z)[2];
}
float& Vector3::zwrap::operator=(float b) {
return parent(z)[2] = b;
}
To finish off an old question: No. It makes me sad, but you can't do it.
You can get close. Things like:
Vector3.x() = 42;
or
Vector3.x(42);
or
Vector3.n.x = 42;
or even
Vector3.x = 42; //At the expense of almost quadrupling the size of Vector3!
are within reach (see the other answers - they're all very good). But my ideal
Vector3.x = 42; //In only 12 bytes...
just isn't doable. Not if you want to inherit all your functions from the base class.
In the end, the code in question ended up getting tweaked quite a bit - it's now strictly 4-member vectors (x, y, z, w), uses SSE for vector math, and has multiple geometry classes (Point, Vector, Scale, etc.), so inheriting core functions is no longer an option for type-correctness reasons. So it goes.
Hope this saves someone else a few days of frustrated searching!