I'm a newbie using V++ and I've been wondering about some memory behavior.
I wrote similar classes to what is causing me problems. The questions are
written in the comments of the code.
class A
{
private:
int _number;
public:
A(int number) : _number(number)
{}
const int& getNumber() const
{
return _number;
}
void setNumber(const int& number)
{
_number = number;
}
}
class B
{
private:
A _a;
bool _hasA;
public:
B() : _hasA(false)
{}
B(const A & a) : _a(a), _hasA(true)
{}
void setA(const A & a)
{
_a = a;
}
const A& getA() const
{
return _a;
}
const bool hasA() const
{
return _hasA;
}
void removeA()
{
// ??
}
}
int main()
{
A a(5);
B b1; // Is the A space allocated even if no value is affected to it ?
B b2(a);
b1.setA(b2.getA()); // I actually want to move "a" from b2 to b1 without leaving it in b2
b1.removeA(); // Do I need to write a removeA() function and how would it be?
}
b1.setA(b2.getA()); copies A into b1 too instead of moving it.
Thanks for your help.
EDIT: To answer those who are confused like I just was:
Me : I just understood that when instanciating b1 it needed the A::A() constructor. I thought it'd be like "null" or something if I created b1 without instantiating _a.
Zac Howland: #SanjamX I see your confusion now. In managed languages, (most) everything is a pointer, so if you do not instantiate it (e.g. A a instead of A a = new A()), it is just a null pointer. In C/C++, if you declare something as A a, you instantiated it "on the stack". It is an automatic variable that will be deallocated when it goes out of scope. You are still instantiating it, however. This question may help you understand better.
B b1();
That does not do what you think it does. It is declaring a function b1 that takes no parameters and returns a B.
b1.setA(b2.getA());
b1.removeA();
Because of the previous situation, the 2 lines above will give you a compiler error.
The "move" you are asking about will actually be a copy (in this case). You can use the C++11 move semantics to do an actual move, but it is entirely unnecessary with the current code. Alternatively, you can change your class to do a move using pointers (which could potentially be useful) - which would use std::unique_ptr<A> _a, instead of A _a.
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.
As far as I know, "this" pointer is the parameter that is inserted into function by Compiler like below :
class Sample {
private:
int a;
public:
void setA(int a) {
this->a = a;
}
};
Sample ob;
ob.setA(5); -> ob.setA(&ob, 5);
class Sample {
private:
int a;
public:
void setA(Sample* this, int a) {
this->a = a;
}
};
Btw, I found something confusing code that assigning the "this" pointer to const field. (Consult below)
class Test {
int data;
public:
Test* const test = this;
Test(int data = 1) : data(data) { }
Test(Test &test) : data(test.data) { }
};
(It has no compile Errors and runs well!)
If it is true that "this" pointer is conveyed via function, How can it be?
I have no idea..
Could you give me some advice please? I'm appreciate for your any replies.
This syntax:
Test* const test = this;
comes from C++11. It means "initialize test to this inside any non-copy constructor which does not already initialize test explicitly".
As a result, this code is executed inside the constructor, and this is perfectly valid. However, the benefit of doing this sort of initialization is unclear, and dependening on the usage of test might be dangerous.
The properties of the class (Test.test in this case) are initialized implicitly by code that is generated by the compiler. There is a function, and it does receive the this pointer, but it's all generated by the compiler which is why you can't see it.
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 have situation similar to included:
class A
{
public:
A(shared_ptr<B>);
}
class B : public enable_shared_from_this<B>
{
const shared_ptr<A> a;
}
I can't have shared_ptr to B before construction, so before a is initialized. So, I need to initialize my constant field after construction (I think it denies RAII), or just construct it later (so it can't be const, so it denies const-correctness, and also looks like not-too-consistent with RAII).
It looks like propably common situation. Is there any the cleanest way to handle this? How would you do this?
I would solve this by not having const members, plain and simple. They are generally much more trouble than they're worth (they make the class non-assignable, not even move-assignable, for example).
a is private, so only the class itself can access it. Thus it should be enough to document "a should never be modified after being initialised!!!". If you fear that won't be enough (or the class has friends outside your control), you can make this even more obvious like this:
class B : public enable_shared_from_this<B>
{
const std::shared_ptr<A>& a() { return _use_this_ONLY_for_initialising_a; }
std::shared_ptr<A> _use_this_ONLY_for_initialising_a;
};
Such a situation is a good indicator to refactor your code. Think about whether B should actually inhert from A or be a member of A before finding a way around this problem...
.. because it is probably going to be to remove the constness of your object - and probably not use shared_ptr (you have a cyclical reference there, so ref-counting alone will never be able to destroy your objects!).
If A doesn't actually keep a copy of the shared_ptr<B> you pass it (just uses the B briefly) then you can make this work (see below) but:
If A doesn't keep a reference to the B then it could just take a B& or B* argument, not a shared_ptr<B>, so you should change the design.
If A does keep a reference then you're going to have a circular reference, so you should change the design.
This works, but is really, really horrible and would be easy to introduce bugs, and is generally a bad idea, I probably shouldn't even be showing it, just change your design to avoid circular dependencies:
#include <memory>
#include <iostream>
class B;
class A
{
public:
A(std::shared_ptr<B> b);
};
class B : public std::enable_shared_from_this<B>
{
// return a shared_ptr<B> that owns `this` but with a
// null deleter. This does not share ownership with
// the result of shared_from_this(), but is usable
// in the B::B constructor.
std::shared_ptr<B> non_owning_shared_from_this()
{
struct null_deleter {
void operator()(void*) const { }
};
return std::shared_ptr<B>(this, null_deleter());
}
public:
B(int id)
: m_id(id), a(std::make_shared<A>(non_owning_shared_from_this()))
{ }
int id() const { return m_id; }
private:
int m_id;
const std::shared_ptr<A> a;
};
A::A(std::shared_ptr<B> b)
{
std::cout << b->id() << std::endl;
}
int main()
{
auto b = std::make_shared<B>(42);
}
I have these classes:
class A
{
};
class B : public A
{
public:
B(int val);
private:
int* m_int;
};
B::B(int val)
{
m_int = &val;
}
I call the code like so, inside 1 function, i know the vars will be destroyed once they are out of scope, but I only need them in this function:
{
...
int _int = 0;
B obj(_int);
A *obj2 = &obj;
_int++;
...
}
The problem is that _int is changing to 1, but m_int stays the same. I need m_int to reflect what the value in _int is, without the need to update it with code. I thought having a pointer to a memory location would work?
The second problem is that when I hover my mouse over obj2, to see the values of obj, I get the message "children could not be evaluated".
I'm not too sure whether the following is good advice for a novice, but using a reference like this would work:
class B : A
{
public:
explicit B(int& val);
private:
int* m_int;
};
B::B(int& val)
{
m_int = &val;
}
I'm a bit worried that it is actually a sign of bad design. If it is just for learning purposes, go right ahead, understanding is always important
The pointer m_int will stay the same but the value pointed to *m_int will change, you'll also have to pass the value val by reference to the function.
EDIT: Saw your edited question, since this is done from the constructor you can do:
class B : A
{
public:
B(int& val) : m_int(val) {}
private:
int& m_int;
};
To have m_int reference the same variable.
If you want to change value of _int you should pass it's pointer, they way you're doing now is call by value.
B::B(int* val)
{
m_int = val; // not ref
}
and m_int should be of type int* not int
For second problem, you're storing a value of derived class in a pointer to base, So when you try to see what's inside obj2 you only see the part of type base, that's why you get message children cannot be evaluated.
Edit--
If you want to see what actually is in obj2, you should cast it to derived type again. And you may not always know that at runtime...