I came across some code I don't understand. In a class B there is a pointer to a method of a different class A but the pointer has no variable. How can I call this method in class B?
This is part of a larger project of someone else, i would like to preserve the existing code.
class A {
public:
A *root() { return this; }
};
class B {
public:
A *root();
};
I expected something like this
A *myA = root();
inside class B to work but i get linker error "undefined reference to ...". The question is more how this construction is called, what is it useful for and how to use it.
As in the comments standing, there is no implementation of B::root(). Maybe the code you have has beside the .h file a .cpp or .hpp file, where the implementation of B::root() stands - or there exists a library with it.
A valid implementation could be A* B::root() { return new A(); }. You can just grep for B::root.
To call B::root(), a simple B b; A* as = b.root(); is enough. Same as with A::root(), where a simple call could be A a; A* as = a.root();
class A {
public:
A *root() { return this; }
};
class B {
public:
A *root();
};
A* B::root() { return new A(); }
int main() {
A a;
B b;
A* asa = a.root();
A* asb = b.root();
return 0;
}
Related
I am stuck with creating a mock for a concrete class.
I know that is not a great idea to do this but I'm not not allowed to change production code.
My code is similar with:
Class A
{
public:
A(B* b)
{
this->b = b;
}
.........................
void function_from_a_to_test(<arg>)
{
if(!b)
b->function_from_b();
else
//something to do
}
private:
B * b;
};
class B
{
........
public:
void function_from_b();
......
};
class MockB : public B , testing::Mock //i don't know why I can that, B is not virtual
{
MOCK_METHOD(function_from_b, void, (void));
};
A_Test :testing::Test{
SetUp()
{
b = new B();
a = new A(b);
}
TearDown()
{
delete b ;
delete a ;
}
void set_b(B * bb)
{
a->b = bb;
}
.........................
}
In order to test I used Test_f
TEST_F(A_Test, Test_function_from_a_to_test)
{
//arrange
//act
B * b_t = new MockB();
set_b(b_t);
EXPECT_CALL(*(static_cast<MockB> b_t), function_from_b))
.Times(10);
function_from_a_to_test(arg);
}
It's seems that the test is passed but i got memory leak at static cast.
And If I store the result of static cast in another variable (in order to delete it), the expect call having that variable is failing.
I know that is not really a good practice, but I can not change the production code.
Has somebody a idea how to solve it?
Or a better way to test this?
You can't mock a non-virtual function using inheritance. You would have to have to define a mock class that implements the functions needed by the code under test, and then have a way to replace the concrete class with the mock class. Read more about it here.
To be honest, I have no idea what the result of that static_cast is, but it's probably not good.
The only way I can think of to do what you want to do without changing production code is to use a different include path in your test project that would allow completely replacing the concrete class B with the mock class B. This may or may not be possible, depending on how your production code is structured.
If you're lucky enough to have class B defined in a separate header file, then it's easy: Make a mock header file with the same name but different folder, and make sure that folder appears in the include path before the production header file's location.
Production B.h file (in original location and unmodified):
class B
{
public:
void function_from_b() {}
};
Mock B.h file (in test code location):
class B
{
public:
MOCK_METHOD(void, function_from_b, ());
};
Somewhere in production code (unmodified):
#include "B.h" // Will load original or mock depending on include path
class A
{
public:
A(B *b)
{
m_b = b;
}
void function_from_a_to_test(int arg)
{
if (m_b)
m_b->function_from_b();
else
; //something to do
}
private:
B *m_b;
}
Test code:
TEST(A_Test, Test_function_from_a_to_test)
{
B b;
A a(&b);
EXPECT_CALL(b, function_from_b)
.Times(1);
a.function_from_a_to_test(0);
}
On my work I have met with one bug which can be described as follows.
There are two classes, class A and class B:
class A
{
public:
void print(){}
};
class B
{
A* a;
public:
void init(A* _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
A* a;
B* b;
b->init(a);
// some code .....
delete a; // line 1
a = NULL;
// some code .....
b->PrintWithA(); // line 2
Object "b" doesn't know nothing about state of object "a". In line 1 "a"object has been deleted but on line 2 we continue to use it. When there are a lot of code it is very easy to make such mistake.
My question is the following - which approch to use to avoid some mistakes? I guess I could use observer pattern - but I think it is unjustifiably expensive solution.
Thank's.
You should use a weak ptr (http://en.cppreference.com/w/cpp/memory/weak_ptr)
basically you can provide class B with a weak ptr of A.
whenever comes time to access A, you can try to lock the weak ptr to see if it's still valid.
#include <memory>
class A
{
public:
void print(){}
};
class B
{
std::weak_ptr<A> a;
public:
void init(std::weak_ptr<A> _a) {
a = _a;
}
void PrintWithA()
{
if (auto spt = a.lock()) {
spt->print();
}
}
};
int main()
{
std::shared_ptr<A> a = std::make_shared<A>();
std::unique_ptr<B> b = std::make_unique<B>();
b->init(a);
// some code .....
a = nullptr;
// some code .....
b->PrintWithA(); // line 2
return 0;
}
To guard against that, either B needs to take ownership of the lifetime of A when the object B is constructed, or you need to make A reference counted.
C++11 I think has the concept of a shared pointer which maintains the references and will prevent the object A from being deleted if someone has a reference. See std::shared_ptr
If you are not using C++11 there is boost::shared_ptr which does essentially the same thing. But you need the boost library which I personally prefer not to use, but it's up to you.
Use them like this:
typedef std::shared_ptr<A> A_ptr;
A_ptr a = new A();
class B
{
A_ptr a;
public:
void B(A_ptr _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
Otherwise you could put something together yourself. Something along the lines of:
class A
{
public:
A(){
ref_count = 1;
}
void print(){}
void grab() {
ref_count++;
}
void release() {
ref_count--;
if (ref_count <= 0)
~A();
}
private:
int ref_count;
~A(){
delete this;
}
};
Inside B you'd assign the pointer and call grab();
Rather than call delete (which wouldn't work because it's private) you'd call
a->release() on the pointer.
Now this is not particularly fantastic because you can't use this form:
A a;
So it's not ideal. But if you're using some compiler that doesn't have a shared_ptr and you don't mind the limitation you may use this or a form of it. In general, use shared_ptr.
First of all, the line that says A* a; should probably be A* a = new A;.
In c++ you need to encode this awareness explicitly, it's not done automatically.
One thing you can do is check if _a is NULL inside PrintWithA, but this won't work if you make sure that you always set your pointers to NULL after delete[]ing them (which you've done)
I wonder how it is possible to access an object that was created in the main function from another class.
main.cpp
#include"ClassA.h";
#include"ClassB.h";
int main()
{
ClassA objectA;
return 0;
}
ClassA.h
#pragma once
class ClassA
{
public:
ClassA():_privateVar(100)
{};
~ClassA()
{};
//Getters
float getPrivateVarA(){ return _privateVarA; };
//Setters
void setPrivateVarA(float privateVarA){ _privateVarA = privateVarA; };
private:
//Just a value
float _privateVarA;
};
ClassB.h
#pragma once
class ClassB
{
public:
ClassB():_privateVarB(50)
{ };
~ClassB()
{ };
//This is what i´m trying to achieve: Acces objectA
// like this: objectA.getPrivateVarA(); or objectA.setPrivateVarA;
int getPrivateVarB(){return _privateVarB;};
private:
int _privateVarB;
};
I've been all week searching for an answer to this and found nothing...
If anyone knows of some books or have any information on how I can get there would be grateful.
Thank you.
You placed your question in the middle of the ClassB declaration. You can't execute code there. Whatever you do must be done from within a function.
A function in ClassB can be defined so that it accepts a reference or pointer to a ClassA. Then that reference can be used to call getPrivateVarA().
In other words, if class B needs to access a class A then it is up to your code to initialize B with the required reference. This can be done when creating the B object, or when calling a method of the B object.
objectA has function-local scope within main(). By definition, objects can be directly accessed only within their visible scope. That's what C++ is all about.
Of course, if you pass a reference or a pointer to this object, to some other function, that other function can access the instantiated object indirectly, via the pointer or the reference.
I can't say with 100% certainty that you can't, but you definitely should not be doing that. If you want to use an object created in a different scope then you need to pass it into the scope you want to access it from either by value, reference or via a pointer.
First Class A:
class A {
public:
ClassA() : _privateVar(100) {}
~ClassA() {}
float getPrivateVarA() { return _privateVar; }
void setPrivateVarA(float val) { _privateVar = val; }
private:
float _privateVar;
};
First Class B:
class B {
public:
ClassB() : _privateVar(50) {}
~ClassB() {}
// by copy
float getPrivateVarB_byCopy(ClassA a) {
return _privateVar + a.getPrivateVarA();
}
// by reference
float getPrivateVarB_byRef(ClassA &a) {
return _privateVar + a.getPrivateVarA();
}
// by pointer
float getPrivateVarB_byPointer(ClassA *a) {
return _privateVar + a->getPrivateVarA();
}
float setPrivateVarB(float val) { _privateVar = val; }
private:
float _privateVar;
};
Now for main.
int main(void) {
ClassB b;
ClassA a; // for copy and ref
ClassA *a2 = new ClassA(); // for pointer
b.getPrivateVarB_byCopy(a); // => 150
b.getPrivateVarB_byRef(a); // => 150
b.getPrivateVarB_byPointer(a2); // => 150
delete a2; // clean up pointer
return 0;
}
Although your example this type of access is really not a good idea, not sure why you'd want to go about doing things this way.
I am writing a "filesystem" abstraction in C++, with the following inheritance hierarchy:
[Node]
^
|
+----[Dir]
|
+----[File]
Where Node defines all the behavior identical to both (Name, time last modified, etc.) however, I have a Node method called getParent() that returns a type Dir *. This works fine, because although Dir.h obviously needs to know the implementation specification in Node.h, Node.h doesn't need to know about what's in Dir.h so I can use a forward declaration. Great.
However, I recently decided to add in multiple inheritance so I can support "snapshots" of the filesystem at a certain time. These are read-only versions of the "live" Node File and Dir classes, and since the live versions can be read from as well as written to, I have each live version inherit from its snapshot dual:
[NodeSnapshot] <------ [Node]
^ ^
| |
+---[DirSnapshot]<---+---[Dir]
| |
+---[FileSnapshot]<--+---[File]
Therefore, Dir inherits from both Node and DirSnapshot, and File inherits from both FileSnapshot and Node. Everything looks good to be so far, until we get to the declaration of getParent(). In NodeSnapshot, I return a DirSnapshot *. No problem, I can use a forward declaration again. However, in Node, I want to return Dir *. I, as a programmer, know that Dir is a subtype of DirSnapshot, however the compiler has no way of knowing this because a forward declaration doesn't have any of this useful information embedded in it.
Is it possible to inform the compiler that this forward declaration is a subclass and therefore it shouldn't tell me that the return type of Dir::getParent() does not covary with that of DirSnapshot::getParent()?
It is possible to implement/emulate return type covariance without any language support, though solutions tend to be verbose. On the other hand, mutually recursive definitions are no problem. One needs to use non-virtual public (inline) functions that call virtual private functions. It is a useful technique, some even argue that all interfaces should be implemented like this.
Here's an example:
// forward declare classes
class A;
class B;
class AA;
class BB;
// parents
class A
{
virtual B* getB_impl();
public:
B* getB() { return getB_impl(); }
};
class B
{
virtual A* getA_impl();
public:
A* getA() { return getA_impl(); }
};
// kids
class AA : public A
{
virtual BB* getBB_impl();
B* getB_impl();
public:
BB* getB() { return getBB_impl(); }
};
class BB : public B
{
virtual AA* getAA_impl();
A* getA_impl();
public:
AA* getA() { return getAA_impl(); }
};
// implement parents
B* A::getB_impl() { return new B; }
A* B::getA_impl() { return new A; }
// implement kids
B* AA::getB_impl() { return getBB_impl(); }
BB* AA::getBB_impl() { return new BB; }
A* BB::getA_impl() { return getAA_impl(); }
AA* BB::getAA_impl() { return new AA; }
// check
A a; B b;
A* pa; B* pb;
AA aa; BB bb;
AA* paa; BB* pbb;
pa = b.getA();
pb = a.getB();
pa = bb.getA();
pb = aa.getB();
paa = bb.getA();
pbb = aa.getB();
You should exclude multiple inheritance from your project.
Snapshot is associated with current state of filesystem/dir/file, so it's data.
You need inheritance when you don't want to replicate functional and inherit file and dir from node is acceptable. However since snapshot is data it is likely you need to move node data to some struct, special file/dir data to other structs, all of them will be returned or saved/restored on some functions callings, that will be overloaded due inheritance.
[Node] [Node Data]
^
|
+----[Dir] [Node Data][Dir Special Data]
|
+----[File] [Node Data][File Special Data]
virtual void Node::Snapshot()
{
//some code operating with Node Data (saving on disk for ex)
}
virtual void Dir::Snapshot()
{
Node::Snapshot();
//some code operating with Special Dir Data (saving on disk for ex)
}
virtual void File::Snapshot()
{
Node::Snapshot();
//some code operating with Special File Data (saving on disk for ex)
}
If I have a pointer to a base class A in C++, how would I be able to tell in my code that the pointer is to a derived class B or C?
Assuming the base class A is polymorphic (i.e. it has at least one virtual function), you can use dynamic_cast. Given an A* ap;:
if (B* bp = dynamic_cast<B*>(ap)) {
// the object is a B
}
else if (C* cp = dynamic_cast<C*>(ap)) {
// the object is a C
}
You generally shouldn't need to know:
struct A {
virtual int generate_foo() = 0;
};
struct B : A {
int generate_foo() { return 42; }
};
struct C : A {
i_;
C(int i) : i_(i) { }
int generate_foo() { return i_++; }
};
If you have an A* you (1) know that it has a generate_foo() method, and (2) know that generate_foo() will generate an appropriate foo for whatever object you really do have. In general that should be enough and you should be able to keep track of when you have an A*.
Philosophically, the designers of C++ spent years trying to avoid adding runtime type information because it' too easily used incorrectly. However, they eventually decided that they were on the wrong end of a losing battle and added dynamic_cast and typeinfo(). C++0x will add more.