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.
Related
Here if I leave class B as empty then total how many vtables will be created here ?
#include <bits/stdc++.h>
using namespace std;
class A{
public:
virtual void display(){
cout<<"A Class"<<endl;
}
};
class B: public A{
public:
};
int main()
{
A *ob = new B();
ob->display();//A Class
return 0;
}
I was assuming still 2 vtable will be created one in A and 1 in B but for Class B it will be empty and as per design of c++ if we call display function then if it doesn't find the function in its vtable then it will look for the vtable in parent class and will set the binding of that function with vptr but, I am not sure of that.
Can anybody explain with the exact concept
I tired finding the answer over the internet but, didn't get the desired answer
Practically B needs some run time type information, which is typically stored as part of the "vtable" , that is distinct from A.
This is because:
bool test(A* a) {
return dynamic_cast<B*>(a);
}
has to behave differently if we pass a pointer-to-B or a pointer-to-A.
A "typical" way to implement vtables in C++ looks like this:
using vfunc = void(*)(void*);
template<auto creator>
static auto const* get_vtable() {
static const auto table = creator();
return &table;
}
struct A_vtable {
void const* rtti;
void(*display)(void*);
};
A_vtable create_A_vtable_A() {
return {
"This is class A!",
[](void* self) {
std::cout<<"A Class"<<std::endl;
}
};
}
struct A {
A_vtable const* vtable;
A():vtable(get_vtable<&create_A_vtable_A>()) {}
};
struct B_vtable:A_vtable {
};
B_vtable create_B_vtable_B() {
B_vtable vtable = create_A_vtable_A;
vtable.rtti = "This is class B!";
}
struct B:A {
B() {
vtable = get_vtable<&create_B_vtable_B>();
}
};
with the note that my runtime type information is intentionally a joke.
That RTTI information in a real situation will tell you how what the runtime type is, and how to get a pointer to the most-derived type. Here I just store a void pointer to a string.
But you'll notice I moved the vtable pointer to a different table in the constructor of B. This is basically how compilers do it (the standard gives compilers lots of freedom, so you cannot assume it looks anything at all like the above, it might not even have a vtable).
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.
I wrote this.
class A { };
class B : public A
{
public:
static B Convert(const A &a) { return static_cast<const B&>(a); }
};
int main()
{
A a;
B b = B::Convert(a);
}
But I would like to have this, do you know how?
B b = a.Convert();
Thank you in advance for your answers! ^^
Generally I would say, don't do this. Use dynamic_cast<B*>(&a) instead See this post
But if you can check if a is of type B, you could implement it as follows:
class A {
// ...
B& Convert() { return return static_cast<B&>(*this); }
}
BUT be very care full to check if this is even a valid conversion otherwise you might get undefined behaviour during runtime !!!
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
I have the following classes :
class A {
};
class B : public A {
};
class P {
private:
std::list<A*> l
protected:
virtual void DoIt(A* a) = 0;
public:
void WorkerThread() { for (it=l.begin(); it!=l.end(); it++) DoIt(*it); }
};
class Q : public P
{
protected:
void DoIt(A* a) { print("false"); }
void DoIt(B* b) { print("true"); }
};
Unfortunately, DoIt(B* b) will never get called.
DoIt(A* a) will always be called even if I add B objects to the list.
What can I do to make DoIt(B* b) called ?
Is it possible to achieve this if B does not know Q ?
Is it possible to achieve this if without dynamic cast ?
Thank you
Well, nobody's really directly answered your question (well, heavyd tried) so I will. Some other "answers" here are actually more helpful for fixing your problem though.
The issue is that void DoIt(B*) is NOT an override of the virtual function DoIt(A*). It's an overload. There's a HUGE difference.
When you say that DoIt(B*) is not called when you pass a B* I have to assume that you're holding references or pointers to you Q through a pointer to something higher up the higherarchy. In those cases the static name resolution only finds DoIt(A*) and since B* is-a A* it gets upcasted and that's the version that gets called. Since it is virtual the override in Q is what gets called.
If you had a pointer to Q as a pointer to Q though, and called DoIt with a B* the DoIt(B*) function should get called. At this point, double dispatch is not needed and is not used.
You need double dispatch when you have two abstract types and a function that must behave differently based on the concrete types of both abstractions. This is what you're attempting to do when you call DoIt with B on Q at a higher level than static naming provides. There are too many methods that answer different needs to be able to suggest one solution over another in your case, don't really know what you're trying to solve. In fact, you might not even need it! A better approach for you might be to implement DoIt(B*) as a virtual function in the top of your higherarchy.
I would suggest that you get Andre Alexandrescu's book, Modern C++ Design, and look it over. He explains a pretty darn cool visitor implementation as well as a multiple dispatch mechanism that scales. Don't stop there though, there's other great implementations that can answer the question differently.
Good luck.
You are looking for a double dispatch mechanism that is not built into the language. There are different approaches on how this can be implemented based on the visitor pattern. Google for double-dispatch in C++. Note that this is a patch and not easily extended to big hierarchies:
struct visitor;
struct A {
virtual void accept( visitor& v ) { v(*this); }
};
struct B {
virtual void accept( visitor& v ) { v(*this); }
};
struct visitor {
virtual void operator()( A& ) = 0;
virtual void operator()( B& ) = 0;
};
struct myvisitor : visitor {
void operator( A& ) { std::cout << "A" << std::endl; }
void operator( B& ) { std::cout << "B" << std::endl; }
};
int main() {
std::vector<A*> data = ...
myvisitor v;
for ( std::vector<A*>::iterator it = data.begin(), end = data.end(); it != end; ++it )
{
(*it)->accept( v );
}
}
The usual mechanism will be used and accept will be dispatched to the final overrider of the method, which in turn will call the visitor method. Now, at that point, the static type of the argument to the visitor operator() is in fact the actual type that you want to call the function with.
DoIt(B* b) will never get called because you are never passing in objects of type B*, every time you call DoIt, at least in the given code, you are passing in objects of type A*.
Consider the situation where the override of Doit(A* a) did not exist. Your current code would not compile because it the compiler cannot implicitly cast an object of type A* to B*.
What are you expecting the behaviour to be if someone passes in an A* but the underlying type is really a B?
You might be looking for something like this:
class A
{
public:
virtual ~A() {}
virtual bool isB() const { return false; }
};
class B : public A
{
public:
bool isB() const { return true; }
};
void Q::DoIt( A* a )
{
print( a->isB() ? "true" : "false" );
}
You're looking for multiple dispatch or multimethods. Wikipedia has a nice example for c++; link here.
What you are trying to do is known as multiple dispatch and won't work in C++ because function overloading is static. Take a look at the wikipedia article for some possible work arounds.
For example, if you don't want the logic for the DoIt functionality in the A and B classes themselves as a virtual function then you could use the dynamic_cast method:
class A {
};
class B : public A {
};
class P : protected std::list<A*>
{
protected:
virtual void DoIt(A* a) = 0;
public:
void WorkerThread() { for (it=begin(); it!=end(); it++) DoIt(*it); }
};
class Q : public P
{
protected:
void DoIt(A* a) {
if(B *b = dynamic_cast<B*>(a)) {
// It's a B*, you can "use" b here
print("true");
} else {
// It's an A*
print("false");
}
}
};