I have 2 class:
class A
{
int aa;
};
class B
{
int bb;
};
class C
{
public:
bool equal(A& av,B& bv)
{
return (av.aa==bv.bb);
}
};
Of course, class C has compilation error cause of private members' access.
Is there a way to implement that equal() member of class C ?
A good solution might be to provide getters in A and B classes.
This way you keep everything encapsulated.
e.g.
class A
{
int aa;
public:
int GetAA()
{
return aa ;
}
};
This is a great scenario for using friend functions:
// forwarding references to each of the classes
class A;
class B;
class C
{
public:
bool equal(A& av,B& bv);
// notice we cannot implement equal() here,
// because A and B have not been defined yet,
// even though they have been declared.
};
class A
{
private:
int aa;
// Simply register to be a friend of A with our 'C::equal' function,
// so that we can access 'aa'
friend bool C::equal(A&, B&);
};
class B
{
private:
int bb;
// Once again, we register as a friend of C::equal,
// this time to access 'bb'
friend bool C::equal(A&, B&);
};
// finally, now that A and B have been fully defined,
// we can implement our equal method:
bool C::equal(A&av, B&bv)
{
return (av.aa == bv.bb);
}
// Sample Usage
int main()
{
A a = A();
B b = B();
C c = C();
c.equal(a, b);
}
I see questions like this and I ask why. There'a apparently no relationship between class A and class B beyond that they have an int.
The way to make this compile is to make C a friend of A and B, or at least make the equal function in C a friend of A and B (with careful use of forward declarations).
class A;
class B;
class C { static bool equal(A const &, B const &); };
class A { friend bool C::equal(A const &, B const &) };
class B { friend bool C::equal(A const &, B const &) };
bool C::equal(A& const &a, B const &b) { return a.a == b.b; }
Please note the const qualifier as it is unlikely that a comparison operator is meant to alter its input. Moreoever I have made it a static function as it doesn't use any of the members of C - it is completely unrelated. (as per your snippet).
Basically - that's how you do it. But don't do it without a LOT of thought. Just because apples and oranges both have pips, doesn't mean there's a lot of point in comparing the numbers of pips.
You can make the classes friends with each other.
But, as pointed out in comments, that's pretty horrible in most cases. The reason the member is private has to be because outside parties shouldn't access it directly.
So, either add operator==() overloads to A and B that can be used (i.e. an bool A::equal(const B&) const; method), or add accessors to return the value for external comparison.
Form friendship with two classes(c & a , c & b) and then compare.
If they are private and cannot be accessed via any kind of public interface it means conceptually they have nothing in common. so add public getAA getBB and use it to make the comparator between objects. I dislike friendship. A lot.
You could make A and B to be friend of C or add int GetVar() const methods to A and B classes.
Why do you need this?
Combine behaviour with the data.
class C
{
public:
void doSomething()
{
if(aa == bb) {
doThis();
} else
doThat();
}
}
private:
int aa;
int bb;
};
Without commenting on the relevance of the request, or alternatives for the presumed underlying reason, I believe you can compare private members thru Reflection:
FieldInfo AInfo = av.GetType().GetField("aa", BindingFlags.NonPublic | BindingFlags.Instance);
int AValue = (int) AInfo.GetValue(av);
etcetera
Related
aI find this question to be interesting for other people, too. So I choose this one to finally ask my first question on Stack Overflow. A minimal description of the situation is the following:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
}
EDIT: Setting the members of A to be private and using getters and setters is not a solution to my problem. However, I hope for a solution as easy as this, because I well might miss something easy, due to my lack of experience in programming.
Now, I need any yet-to-be-implemented method of B to have only const access to A.m_first while having non-const access to A.m_second, and similarly, I need any other code using something of type B having the same access restrictions, when accessing B.a. Of course, this is impossible (at least from my humble point of view).
Nevertheless, my question is:
How is it possible to enforce on the class B such a const-restriction of the access to a non-const member variable?
EDIT With private m_first and m_second and a getters and setters for m_first and m_second the situation would be the same. Then the questions is: How to restrict the access of B to the const getter of m_first, and deny B the access to the setter of m_first, while at the same time allow B to use the setter of m_second?
The above is the question. However, without the following context this question might be incomplete as it illustrates the significance of the question. The actual situation I am facing is the following:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
public:
// A lot of code.
private:
// A lot of code.
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
class C { // shoud be const on a.m_second
private:
A& a;
public:
C(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
/*
* A lot of other Code that is supposed to work with A, B and C. The following three
* functions serve as an example. As you see, everything is manipulating essentially
* the same data from a.
*/
void f(A& a, /* other args */ ) { /* ... */ };
void g(B& b, /* other args */ ) { /* ... */ }; // shoud be const on b.a.m_first by design
int h(C& c, /* other args */ ) { /* ... */ }; // shoud be const on c.a.m_second by design
int main() {
A a;
B b = B(a);
C c = C(a);
f(a, /* other args */ );
g(b, /* other args */ );
return h(c, /* other args */ );
}
Again, I need any yet-to-be-implemented method of B to have only const access to A.m_first while having non-const access to A.m_second. However, for the class C I need this to be exactly the other way round: I need any yet-to-be-implemented method of C to have only const access to A.m_second while having non-const access to A.m_first. Similarily, any Code using something of type B and C should have corresponding access-restrictions.
Again, of course, the question arises: Why do I need this? And the answer is, that the logical structure of the algorithm would be enforced by such a design. Making everything public is only in so far a concern, as neglecting the logical structure by accident leads to hard to find bugs in the code and due to the complexity of the code it is hard to keep track of such restrictions which are not enforced by design.
The best solution I had come up with - but did not yet implement -, is copying the code to two wrapper classes:
class A_first {
public:
const Type_m_first& m_first;
Type_m_second& m_second;
A_first(A&) ; m_first(const A.m_first), m_second(A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
class A_second {
public:
Type_m_first& m_first;
const Type_m_second& m_second;
A_first(A&) ; m_first(A.m_first), m_second(const A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
This is not desirabe, because the code changes a lot over time, and keeping track of the changes in three classes is error-prone. My question is, what to do in such a situation?
I'm highly in doubt whether this is worth the effort, but this might suit your needs:
Instead of passing B and C a reference to A (which would grant them unlimited access to A, which is your whole problem if I understand correctly), only pass them the accessors to the two members. This could look like so:
class B {
private:
std::function<Type_m_first const&()> getConstFirst;
std::function<Type_m_second&()> getNonConstSecond;
public:
B(std::function<Type_m_first const&()> f1, std::function<Type_m_second&()> f2)
: getConstFirst(std::move(f1)), getNonConstSecond(std::move(f2)) {};
void someMethod() {
getConstFirst() = abc; // this won't compile
getNonConstSecond() = xyz; // this will
}
}
Analogous implementation for C.
Then, pass functions to the c'tors of B and C using lambdas that capture the instance of A by reference:
A a;
B b = B(
[&a]() -> auto const& { return a.m_first; },
[&a]() -> auto& { return a.m_second; }
);
C c = C(
[&a]() -> auto& { return a.m_first; },
[&a]() -> auto const& { return a.m_second; }
);
Ok, I have to confess, I just skimmed reading you question, so I might have missed some details. But wouldn't a getter that returns a const reference be what you need?
class A {
private:
Type_m_first m_first;
public:
const Type_m_first & get_m_first() const { return m_first; }
Type_m_second m_second;
}
Here only members of A might modify m_first directly. Everybody else must use the the const reference obtained by get_m_first.
Sorry for the noob question, but I cannot seem to get my head around C++'s static nature. The problem: I have a class that returns an enum and depending on it I have to convert the said class using another class and return a vector. In code:
enum TYPES { TYPE_A, TYPE_B, TYPE C }
class A {
TYPES getType() {}
}
class B : public A {}
class C : public A {}
class D : public A {}
std::vector<?> convert_to_vector(const A& a) {
// depending on what enum is returned by a.getType()
// I have to convert a into B, C, or D class and return std::vector of
// an appropriate type, e.g. int for B, float for C, etc.
}
int main() {
A a;
auto v = convert_to_vector(a);
}
The simplest way would be using switch(a.getType()) but I have different return types in each case and using auto as the return type doesn't work. I have tried templates and template specification, but they don't accept the runtime variable that is return by a.getType(). I guess there must be some simple solution that I'm overlooking here, but I have run out of ideas at this point and would be grateful for any pointers.
Thanks!
You can't change the return type of a C++ function at runtime. But you can use a variant type:
std::variant<std::vector<int>, std::vector<float>> convert_to_vector(const A& a) {
if (a.getType() == TYPE_B)
return std::vector<int>();
if (a.getType() == TYPE_C)
return std::vector<float>();
throw std::logic_error("unsupported type");
}
If you don't have C++17, you can use boost::variant instead of std::variant.
I think instead of deciding the type of a vector on an enum a much better solution would be to have a parent class A which can have a vector inside it which is based on a template variable. In your classes B, C, D you can simply inherit A and specify a template type. So, when you create a new object for B, C, D you will already have a vector member for those objects. You can also have a virtual function convertToVec which you can override in the child classes depending on how you want to convert data into a vector.
template<class T>
class A {
std::vector<T> vec;
std::vector<T> GetVector() { return vec; }
virtual convertToVec() { .... }
}
class B : public A<bool> {}
class C : public A<float> {}
class D : public A<long long int> {}
int main() {
B b;
b.GetVector();
//A* b = new B();
//b->convertToVec();
}
While it's pretty hard to follow what exactly you are trying to achieve here, going to use switch-case is not a good idea, instead you'd better to leverage polymorphism. For example:
class A {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class B {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.convertToVectorB(this);
}
};
class C {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.doSomethingC(this);
}
};
// Aux class
class AuxVectorConverter {
public:
convertToVector(A* a) {
a->convertToVector(this);
}
convertToVectorB(B* b) {
// Do code specific for B
}
convertToVectorC(C* c) {
// Do code specific for B
}
}
int main() {
AuxVectorConverter* aux;
A* a = ...; // Initialize here either with instance of B or C
// Now, based on run time aux class will issue appropriate method.
aux.convertToVector(a);
}
You might find more details here
UPDATE (Based on comment)
An alternative approach could be to define a map from TYPES to some abstract class which will align with the patter from above, e.g.:
// Map has to be initialized with proper implementation
// of action according to type
map<Types, AbstracatAction> actions;
// Latter in the code you can do:
aux.convertToVector(actions[a->getType()]);
And action will be defined pretty similar to hierarchy I've showed above, e.g.
class AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class ActionB: public AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) {
aux.covertToVectorB(this);
}
};
Firstly, I apologize for the bad title naming sense. I am unsure as to how to phrase it correctly.
My problem is that I have four given classes, which I call A, B, C and D for simplicity.
D is a large class containing lots of data.
C is basically a table containing many Ds.
B is a singleton and provides A with an instance of it. B has a member, C* c.
A contains a method which calls B to do something.
I want to test that D has the correct information stored in it, passed through to the program via A.
Here is a simplified version of my code that illustrates the setup.
#include <stdexcept>
#include <string>
#include <vector>
class D {
public:
// Greatly simplified; this class holds much more data in reality.
std::string info {};
};
class C {
private:
std::vector<D*> d {};
public:
D* getD(int dNum) {
return this->d.at(dNum);
}
};
class B {
private:
C* c {};
D* d {};
B() {
this->c = new C();
}
~B() {
delete this->c;
}
B(const B&) = delete;
B& operator=(const B&) = delete;
public:
static B* getInstance() {
static B instance {}; // singleton
return &instance;
}
bool doSomething(const std::string& text) {
int dNum = std::stoi(text); // simplified
try {
this->d = this->c->getD(dNum);
this->d->info += text;
return true;
} catch (const std::out_of_range&) {
return false;
}
}
};
class A {
public:
bool someFunction(const std::string& text) {
return B::getInstance()->doSomething(text);
}
};
My test should somehow look like this.
void test() {
std::string testString {"1"};
A a {};
a.someFunction(testString);
// How can I test that for the 'D' object 'd', that was manipulated by the
// call to 'someFunction', 'd.info == testString'?
}
I have taken a look at stubs and mocks, but I do not understand how to use them in this situation (I have actually never used them).
Once again, sorry if my explanation isn't clear. I am very weak at C++, and thus do not really know how to explain things. As such, even searching for similar questions proved to be impossible, so I apologize if this question has been asked before.
Edit: I do know that I can do this by implementing some getter methods in B to obtain C, but I was hoping for another method.
You have not shown whether you are allocating memory to the class pointers. In a->someFunction(testString);, where does a point to? Then, in class B, neededD = c->getD(dNum); where does c point to? Also, you must change the line requiredD = d->at(dNum); to requiredD = d.at(dNum);. Please provide complete details to understand the problem better.
Hi I am pretty new to C++ and im converting C code to C++. I started by converting all the structs to classes, and added accessors and mutators for the internals, but some structs have other structs inside them. I want to know the best method for setting the internals of a class within a class, such as
struct1.struct2.struct3.i = 5;
where i is an int. Should I be passing as reference using accessors? but seeing as accessors tend to be const would this be something I should do?
something like
class1.get_class2().get_class3().set_i(5) or something if it can be done in this kind of format.
This is probably a dumb question but i have no idea how to do it, Thank You
class1.get_class2().get_class3().set_i(5)
is possible if get_class2() is non-const and returns a non-const pointer reference.
However, this approach completely breaks the encapsulation. The users of class1 should not (and must not) know that class1 uses class2 inside and that in turn uses class3 inside.
If a setter-API is absolutely necessary, then a better approach is do it hierarchically. For example
// User
class1.set_i( 5 );
// class1
class1::set_i( int x ) { class2_obj.set_i( x ); }
// class2
class2::set_i( int x ) { class3_obj.set_i( x ); }
// class3
class3::set_i( int x ) { i_ = x; }
I am not so sure about that ... did you put a class inside a class or an object inside a class ?
something like :
class OBJ1
{
//methods , and other stuff
}
class OBJ2
{
public OBJ1 *O ;
}
is valid , so you can acces a method like :
OBJ2 *N2 ;
N2->O->some_method();
however , something like
class OBJ2
{
class OBJ1;
}
is not valid :P
again... not sure if this is exactly what you asked ...
If you really have a good reason to access your member object via getters and setters, you can do the following:
class A {
public:
void f() const {}
};
class B {
public:
const A &get_a() const {
// the returned reference will be read-only, i.e. only non-const member
// functions can be called, and public members can not be written.
// it needs to be stored in a const A & object.
return a;
}
A &get_writable_a() {
return a;
}
void set_a(A &a) {
//make sure that the assignment operator of A will take care of all the
//dirty internals, such as internal buffers that need to be deleted.
this->a = a;
}
private:
//the member
A a;
};
int main() {
B b;
b.get_a().f();
}
If you don't have a good reason to do so, I'd recommend to simply make it a public member, and access it directy:
class A {
public:
void f() const {}
};
class B {
public:
A a;
};
int main() {
B b;
b.a.f();
}
Isn't that simply much more elegant?
Note that you can use friend to specify other functions or classes that are allowed to directly access your private members.
As was also pointed out in an other answer, in most cases it is a bad idea to make a member object visible to the outside at all.
Let's say I have a class C, with some private attributes, for example the integer j. In the main I create two object of that class, let's say A and B. I need to operate (maybe using a function) over one of the private attributes of those objects. For example the task can be to write in A.j the value 2*(B.j). I can't simply implement a write method and a read method, because it's a much more complicate MPI related problem. Is it possible to implement a function that receives in input two objects and "do some job" over their private attributes? I have to declare it among the other methods of the class?
Thank you.
You can use a friend function to access private and protected class members.
class C {
int j;
friend void f(C& a, const C& b);
};
void f(C& a, const C& b) {
a.j = 2*b.j;
}
Yes, you have to declare the friend in the class definition.
However, depending on what specifically you are trying to do, this may not be the best solution.
Why not just implement get and set methods? That would be the simplest solution...
class A{
int j;
public:
int getJ(){return j;};
void setJ(int j2){j=j2;};
};
int main(){
A B,C;
C.setJ(B.getJ()*2);
return 0;
}
Or by reference:
class A{
int j;
public:
int& access(){return j;};
};
int main(){
A B,C;
C.access() = B.access()*2;
return 0;
}
Or use a friend function:
void doSomething(A &a, A &b){b.j = a.j*2;};
class A{
int j;
friend doSomething(A &a, A &b);
}
As I do not know what you are trying to do, I do not know whether the following solution makes sense in your case. You might try something like the "command pattern", passing a functional telling how the new value of j is calculated from the other object's j (if the syntax looks strange to you, google for "lambda function"):
class MyClass {
private:
int j;
public:
void ModifyBasedOnOtherObject (
const MyClass & other,
const std::function<int (int)> & f
) {
this->j = f (other.j);
}
};
// ...
a.ModifyBasedOnOtherObject (b, [] (int i) { return 2 * i; });