I want to initialize a member (of reference type) in one object to point to a private member of another object (of a different type). I use friend to provide access to the private member. (Please bear with me for a bit, I explain further down why I need to do this.)
Below is a bare minimum version of the code I tried to get started with, and it obviously does not work. Now clearly, I am only trying to initialize the reference with this code Aries a(t.Leo);, but because this is done inside main(), it does not compile.
I went through a number of posts here and on the internet (on the topics of friend and reference), but could not figure out a way to solve it. How could I make this work, or what other approach could I try to bind the reference correctly?
class Aries;
class Taurus {
friend class Aries;
public:
void setLeo(int inLeo) {
Leo = inLeo;
}
private:
int Leo;
};
class Aries {
public:
Aries(const int& inCancer) : Cancer(inCancer) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries a(t.Leo); // Intention: initialize (bind) the Cancer member with t's Leo.
}
Note I know enough C++ to understand why the above practice is considered questionable or bad.
I am working on a research project in a hardware simulation environment, where the testbench is written in C++. The aim of the project is to display the class (private) members as a waveform. The only reliable way of doing this is to make the "waveform maker" class as a friend of the testbench objects, and then have it "stalk" the private members (by creating a reference as above). The other alternative of providing getter methods in the testbench is impractical, since this project would be used with 20 years worth of legacy code.
Just change the Aries constructor to take a Taurus reference, instead of the private int directly. Like so:
class Aries;
class Taurus {
friend class Aries;
public:
void setLeo(int inLeo) {
leo = inLeo;
}
private:
int leo;
};
class Aries {
public:
Aries(const Taurus& inTau) : Cancer(inTau.leo) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries a(t);
}
I know you know that friend is questionable but sometimes necessary, but in this case, these classes don't have to be friends.
struct AriesBinder {
AriesBinder(const int& c) : Cancer(c) {}
const int& Cancer;
};
class Taurus {
public:
void setLeo(int inLeo) {
Leo = inLeo;
}
AriesBinder bind() const { return AriesBinder(Leo); }
private:
int Leo;
};
class Aries {
public:
Aries(const int& inCancer) : Cancer(inCancer) {}
Aries(AriesBinder b) : Cancer(b.Cancer) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries b(t.bind()); // Intention was made clear
}
This is especially useful if many objects like Taurus can be bound to Aries. Also, it decouples the both classes since now the don't have to know each other so you may change the internal representation of Taurus.
The purpose of friendship is to allow access to certain classes that are tightly coupled with yours, often class factories (which assign the members as they construct the class) or some special implementation class.
Therefore in your case, if Aries is a friend of Taurus, you would expect there to be a strong coupling between the two.
Your code doesn't work because you are accessing Taurus.Leo from main, not from Aries.
The purpose of the friendship is particularly to NOT have to create a public "getter" for these variables. That is because these variables are "internal detail" that you do not want the public at large to access, not even to read.
So whilst I'd expect most of the answers above to be possible solutions and will compile and work, you have to understand the concept of friendship and design for your particular case to see if it is an appropriate use.
Related
I am working with an existing C library (that I can't modify) where some structures have opaque fields that must be accessed through specific setters and getters, like in the following crude example (imagining x is private, even though it's written in C).
struct CObject {
int x;
};
void setCObjectX(CObject* o, int x) {
o->x = x;
}
int getCObjectX(CObject* o) {
return o->x;
}
I am writing classes that privately own these types of structures, kind of like wrappers, albeit more complex. I want to expose the relevant fields in a convenient way. At first, I was simply writing setters and getters wherever necessary. However, I thought of something else, and I wanted to know if there are any downsides to the method. It uses function pointers (std::function) to store the C setter-getter pairs and present them as if directly accessing a field instead of functions.
Here is the generic class I wrote to help define such "fake" fields:
template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}
std::function<void(const T&)> setter;
std::function<T()> getter;
};
It is used by defining an instance in the C++ class and setting up setter and getter with the corresponding C functions:
IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};
Here is a complete, working code for testing.
Are there any disadvantages to using this method? Could it lead to eventual dangerous behaviors or something?
The biggest problem I see with your solution is that std::function objects take space inside each instance of IndirectField inside CPPObject, even when CObject type is the same.
You can fix this problem by making function pointers into template parameters:
template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};
Here is how to use this implementation:
class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};
This approach trades two std::function objects for one CObject* pointer per IndirectField. Unfortunately, storing this pointer is required, because you cannot get it from the context inside the template.
Your modified demo.
Are there any disadvantages to using this method?
There's a few things to highlight in your code:
Your getters & setters, being not part of the class, break encapsulation. (Do you really want to tie yourself permanently to this library?)
Your example shows a massive amount of copying being done; which will be slower than it needs to be. (auto operator()(), operator T() to name but 2).
It's taking up more memory than you need to and adds more compexity than just passing around a Cobject. If you don't want things to know that it's a CObject, then create an abstract class and pass that abstract class around (see below for example).
Could it lead to eventual dangerous behaviors or something?
The breaking of encapsulation will result in x changing from any number of routes; and force other things to know about how it's stored in the object. Which is bad.
The creation of IndirectField Means that every object will have to have getters and setters in this way; which is going to be a maintenance nightmare.
Really I think what you're looking for is something like:
struct xProvider {
virtual int getX() const = 0;
virtual void setX() = 0;
};
struct MyCObject : xProvider {
private:
CObject obj;
public:
int getX() const override {return obj.x;}
CObject& getRawObj() {return obj;}
// etc ...
}
And then you just pass a reference / pointer to an xProvider around.
This will remove the dependence on this external C library; allowing you to replace it with your own test struct or a whole new library if you see fit; without having to re-write all your code using it
in a struct by default (as you post) all the fields are public, so they are accessible by client software. I you want to make them accessible to derived classes (you don't need to reimplement anything if you know the field contract and want to access it in a well defined way) they are made protected. And if you want them to be accessed by nobody, then mark them as private.
If the author of such a software doesn't want the fields to be touched by you, he will mark them as private, and then you'll have nothing to do, but to adapt to this behaviour. Failing to do will give you bad consequences.
Suppose you make a field that is modified with a set_myField() method, that calls a list of listeners anytime you make a change. If you bypass the method accessing function, all the listeners (many of them of unknown origin) will be bypassed and won't be notified of the field change. This is quite common in object programming, so you must obey the rules the authors impose to you.
In VS, when you type "class." you are presented with a list of functions you can call. Having to look through a list of 15-20 functions, half or more of which being members is not nice.
I'm extremely interested in finding a system that will hide private member functions or move them to the end of the list, so the user doesn't have to scroll through a list of locked functions.
I have four design types:
1) Namespace method hiding
2) Class based method hiding
3) pimpl version
4) _ prefix
Here is the code for clarity:
#pragma once
#include <memory>
using namespace std; // ignore the fact this is global here
struct Hide_Test_Data
{
int value;
};
namespace Hide_Test_Private_Member_Ns
{
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods
{
public:
Hide_Test_Methods() {}
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods_Alt
{
public:
Hide_Test_Methods_Alt() {}
void private_function() {}
private:
Hide_Test_Data htd_;
};
class Hide_Test
{
public:
Hide_Test() {}
void public_function()
{
_private_function(); // member function prefixed with _
Hide_Test_Private_Member_Ns::private_function(htd_); // namespace version
htm_.private_function(htd_); // subclass version (no private data)
pimpl->private_function(); // pimpl version (with private data)
}
private:
Hide_Test_Data htd_; // class to hold data
Hide_Test_Methods htm_; // class to hold methods
void _private_function() {}; // _ prefixed member function
unique_ptr<Hide_Test_Methods_Alt> pimpl;
};
Note:
The unique_ptr Hide_Test_Methods_Alt version has member data which the standard one doesn't. Both could be implemented in either way.
The _ prefix doesn't hide the member data, but it does move it to the end of the list. This has the advantage of allowing user to see the private functions if they are interested. My main goal is not to hide the private member functions, just to move them out of the way.
Prefixing data with _ 'should' be safe out of global scope according to the standard as long as it is followed with a lowercase letter.
Which of these designs would be more acceptable in general? I imagine I could work with all four of these design types comfortably, but I would rather hear some input on some of the pros and cons I may not have thought of.
Pimpl uses a pointer to ease copying the member data. In the cases where I don't need to copy the member data, is just using a class better or worse?
I have done some research and found a few related threads in this forum:
Hiding private data members? (C++) - this one points out the pimpl idiom (which I added to my examples above).
How to hide private members of a Class? - talks about VS intellisense not hiding private members
Why does Visual Studio's intellisense show private members and functions? - gives an #ifdef solution that I don't really like the idea of.
I think this question is different enough from the others presented to be worthy posting. Thanks as always.
Generally a pimpl pattern is applied when you want to be able to change implementations at link time and as such must be a pointer
Here you don't want the overhead, so you could consider an inner class and an instance of that class as opposed to a pointer:
class fewfunctions
{
class manyfunctions
{
public:
int a1() { return 0; }
int a2() { return 0; }
int a3() { return 0; }
int a4() { return 0; }
// ... many more
};
public:
int b() { return a.a1() + a.a2() + a.a3() +a.a4(); }
private:
manyfunctions a;
};
Only b will show up as a function (a shows up as locked)
I want to achieve the "this line" in the following code. The most logical way is to set GetDog static, but then I cannot use "this". Is there a way to get around it? (not, since I was trying it out, there several lines not relevant to the question)
#include <iostream>
class Dog
{
public:
static int a;
Dog& GetDog(int k)
{
this->a = k;
return *this;
}
int bark()
{
return a*a;
}
};
int Dog::a=0;
int main()
{
Dog puppy;
int i = puppy.GetDog(4).bark();
cout<<i<<endl;
cout<<Dog::a<<endl;
//i = Dog::GetDog(6).bark(); //this line
return 0;
}
Not that doing this has much advantage (just that declaring a class is not required), but i saw it's used in some package I am using. I kind of want to understand how it is done.
class EXOFastFourierTransformFFTW
{
public:
static EXOFastFourierTransformFFTW& GetFFT(size_t length);
virtual void PerformFFT(const EXODoubleWaveform& aWaveform, EXOWaveformFT& aWaveformFT);
...
int main()
{
EXODoubleWaveform doublewf;
EXOWaveformFT wfFT;
...
EXOFastFourierTransformFFTW::GetFFT(doublewf.GetLength()).PerformFFT(doublewf,wfFT);
...
This static function usage also appears in Geant4, which probably is written by physicists, and so they might not do the wisest thing in programming. I still want to want if doing so has other advantages though.
From the vote down before I can see that this probably is not a regular method as I thought it is. Please comment so before doing it.
It seems that it is an implementation of the Meyers singleton.
I explain :
In the example given, the class EXOFastFourierTransformFFTW does not seem to have a constructor but return a reference to a EXOFastFourierTransformFFTW object.
And it looks like this implementation :
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton obj;
return obj;
}
private:
Singleton();
};
From this book from Andrei Alexandrescu, it is said :
This simple and elegant implementation was first published by Scott Meyers; therefore, we'll refer to it as the Meyers Singleton.
The Meyers singleton relies on some compiler magic. A function-static object is initialized when the control flow is first passing its definition. Don't confuse static variables that are initialized at runtime[...]
[...]
In addition, the compiler generates code so that after initialization, the runtime support registers the variable for destruction.
So it good to use static to call a method from a class not instantiated but don't do it if it is not necessary... Here to represent a Singleton Pattern you have to.
But now if you want your class Dog look like that :
class Dog
{
public:
static Dog& GetDog(int k)
{
static Dog obj( k );
return obj;
}
int bark()
{
return a*a;
}
private:
int a;
Dog( int iA ) : a( iA ) {}
};
The static function usage is correct - it lets you use functions from classes without having an instance of the class. The FFT example you gave probably creates an instance within the static function. So in your case, you would instantiate Dog within the GetDog function (just be careful with returning references to local variables!).
You say that you can't use this if you make it static, which is true. But why would you want to access it without using an Object instance if you're going to need to use this at some point in the future? If it has a default value, or something like that, you could declare that elsewhere outside of the function as public static and then access it that way. If you clarify a little bit more as to what you're doing, I'll edit/remove this answer accordingly.
I'm having a rather general design problem and would like to solve it nicely. I'm writing remote control drivers in an embedded C++ project. There will be two types of remote control: joystick or radio. As I'd like the actual remote controller used to be transparent to an user-programmer, I'm also providing a base class for the two. So I'm going to have:
class RemoteControl {};
class JoystickControl : public RemoteControl {};
class RadioControl : public RemoteControl {};
I'd like RemoteContol to just have one public method: RemoteControl.getInput(). This method should return a structure of data in common format, eg. RCInput, so the above method's declaration would be:
class RemoteContol {
virtual RCInput getInput();
};
Now, what's the best way to implement RCInput to be able to pass it to other classes' objects?
I thought an inner class / structure might be a solution, but I never used it yet so can someone please provide an example of implementation and usage?
Thanks in advance.
EDIT:
What I did before was (could be references, this is not important at the moment):
typedef struct {
int a;
int b;
} RCInput;
class RemoteContol {
public:
virtual RCInput getInput() { return rcInput; }
private:
RCInput rcInput;
};
But I thought this way I'm allowing users to create their own structures of type RCInput also not related to RemoteControl, so I was looking for a better design. But maybe there isn't any.
It looks that RCInput is going to be just data, so you can lay it out like that:
RCInput.h file
class RCInput
{
public:
RCInput(double x, double y, double z);
double x() const;
double y() const;
double z() const;
private:
double m_x;
double m_y;
double m_z;
};
RCInput.cpp file:
RCInput::RCInput(double x, double y, double z)
: m_x(x), m_y(y), m_z(z)
{
}
double RCInput::x() const
{
return m_x;
}
double RCInput::y() const
{
return m_y;
}
double RCInput::z() const
{
return m_z;
}
Don't make it a nested class, put it in its own header file. This way the clients which use the inputs do not depend physically on the RemoteControl class header file. In my experience, nested classes are usually an unnecessary complication, they should be best avoided unless really necessary (e.g. iterators in containers).
Also, don't yield to the temptation of making RCInput a struct with public data. You will lose all control over data accesses and creation of data, if you do so (no access logging in getters, no data validation in constructor, no place to set a debugger breakpoint). Remember that forward declaring a class/struct means that some other piece of code will need to be changed if you later decide to turn a struct into class, i.e. instead of
struct RCInput;
you will have to write
class RCInput;
It's better to make it a class from day 1.
If you worry about performance, you can inline the getters.
If you want to store RCInput in containers, add a public default constructor.
If you want to control who can create RCInput, make the constructor private and declare the creating classes as friends (but that makes storing it in containers difficult).
Let's say I have the following class:
class MyClass
{
private:
int Data;
public:
MyClass(int Init)
{
Data = Init;
}
int GetData() const
{
return Data;
}
};
Now, let's say I want to add a method that checks if Data is equal to zero. There are two ways to accomplish this:
bool DataIsZero() const
{
return Data == 0;
}
Or:
bool DataIsZero() const
{
return GetData() == 0;
}
Which is considered better practice? I can see how just using the variable itself might improve readability, but using the getter might make the code easier to maintain.
I don't really like getters/setters for reasons that I won't go into here. They're covered in other questions. However, since you've asked about them, my answer will assume that I use getters/setters; it will not visit all the possible alternatives.
I'd use the getter, for the maintenance reasons to which you allude. Indeed, the abstraction is half the purpose of having the getter in the first place (along with the slightly tighter access control).
If using the variable is more legible than using the getter, then your getter function name is poor and should be reconsidered.
As an aside, it's best to initialise members, not assign them in your constructor body after the fact. In fact, you have to do that with constants, so you might as well start now and remain consistent:
class MyClass
{
private:
int Data;
public:
MyClass(int Init) : Data(Init) {}
int GetData() const {
return Data;
}
};
See how the constructor has changed.
You should use the getter, because if your class moves to a more complex logic in the getter, then you will be insulated from the change. However, if your class provides a public getter, I'd question the logic of creating this method.
It depends.
The former is sufficient for simple classes.
The latter hides the implementation and can support polymorphism, if the method is virtual.