Below is a simplified example of the code I'm working on. There's a function that takes class A pointer as an argument. I want to pass a pointer that has been initialized as nullptr. Without initializing it to some garbage temporary value first, is it possible to pass the nullptr?
class A
{
// stuff
};
class B
{
public:
A* pA1;
A objA;
std::vector<A*> vecB;
B() : pA1 (nullptr) { vecB.push_back(&objA); }
};
void function(A* p);
A* pA2;
int main()
{
B objB;
pA2 = objB.vecB[0];
function(objB.pA1);
return 0;
}
void function(A* p)
{
p = pA2;
}
In a comment, you said:
The point of the function is to make this happen: objB.pA1 = pA2
I think what you need to do is pass a reference to the pointer, instead of passing a pointer by value. Use:
void function(A*& p) // The argument type needs to be "A* &", not "A*"
{
// Now, the change will be visible in the calling program.
p = pA2;
}
Yes. Any raw pointer type can be assigned and therefore initialised with the nullptr value. Example:
static A* pA2 = nullptr;
aschepter has given me the answer in a comment, thank you very much.
void function(A* p)
should be
void function(A*& p)
Related
I got a situation where I have a class B having a protected array of A*. I have an another function A* func() which returns pointers to A objects stored in some other container. (for example std::map<int,A*> or A* arr[]).
For example the following implementation:
#include <iostream>
using namespace std;
class A {
public:
A(int _x): x(_x){};
int x;
};
class B{
public:
B() {
this->arr[0] = new A(1);
this->arr[1] = new A(2);
}
// use idx to index in to the internal array and return A*
A*& operator[](int idx); // return reference to pointer to avoid not a lvalue error
private:
// class B has this private array of A*
A* arr[2];
};
A*& B::operator[](int idx) {
return this->arr[idx]; // 0<=idx<=1
}
A* arr[2];
A* func(int x) {
return arr[x]; // 0<=idx<=1
}
int main() {
arr[0] = new A(12);
arr[1] = new A(14);
B b;
b[1] = func(1); // assign a new value
cout << b[1]->x << endl; // prints 14
}
// memory leaks of this program can be removed using `std::shared_ptr<A>` in the place of `A*`.
In this example, operator[]() returns a reference to a pointer, because returning pointer becomes rvalue and I will not be able to assign value to it (i.e. b[1] = func(1)).
My question is, is this reference to pointer returning recommended (other ways to achieve this )? or is this perfectly fine with raw pointers as well as with shared_ptr?
Thank You!
I have a class that has a setter method which takes a unique_ptr as an argument. That unique_ptr is saved as a class member.
class TestClass {
std::unique_ptr<Tester> sp;
void setTester_Way1(std::unique_ptr<Tester> te) {
auto deleter=std::move(sp);
sp=std::move(te);
}
void setTester_Way2(std::unique_ptr<Tester> te) {
sp=std::move(te);
}
};
Which way is the correct way to set the smart pointer? Does Way2 leak the original pointer of sp?
Way2 is fine, when you assign to a unique_ptr any existing owned pointer will be safely deleted.
As Chris Drew said Way2 is fine. One thing though is that unique_ptr is not copyable/assignable so the only ways to pass a unique_ptr is by reference, r-value reference or by value with move(). Trying to do:
int main()
{
TestClass t;
auto p = std::make_unique<int>(10);
t.setTester_Way2(p);
}
Will fail to compile. Although you can move() p into the function(example).
If you change setTester_Way2() to void setTester_Way2(std::unique_ptr<int>& te) then it will compile. If you change the function to take an rvalue reference and std::move() the pointer into the funcnction:
class TestClass {
std::unique_ptr<int> sp;
public:
void setTester_Way1(std::unique_ptr<int> te) {
auto deleter=std::move(sp);
sp=std::move(te);
}
void setTester_Way2(std::unique_ptr<int>&& te) {
sp=std::move(te);
}
};
int main()
{
TestClass t;
auto p = std::make_unique<int>(10);
t.setTester_Way2(std::move(p));
}
Then it will also compile.
Ok, according to http://dlang.org/const-faq.html#head-const there is no way to have a const pointer to non-const in D. But there is a good practice: declare a field in a class const and compiler let you know if you forget to initialize it. Is there any way to protect myself from forgetting to init pointer field of a class in D?
Yes:
void main() {
// ConstPointerToNonConst!(int) a; // ./b.d(4): Error: variable b.main.a default construction is disabled for type ConstPointerToNonConst!int
int b;
auto a = ConstPointerToNonConst!(int)(&b); // works, it is initialized
*a = 10;
assert(b == 10); // can still write to it like a normal poiinter
a = &b; // but can't rebind it; cannot implicitly convert expression (& b) of type int* to ConstPointerToNonConst!int
}
struct ConstPointerToNonConst(T) {
// get it with a property without a setter so it is read only
#property T* get() { return ptr; }
alias get this;
// disable default construction so the compiler forces initialization
#disable this();
// offer an easy way to initialize
this(T* ptr) {
this.ptr = ptr;
}
private T* ptr;
}
I have a getter method that returns an array declared private.
In .h:
private:
CStringArray a;
In . cpp:
CStringArray &Define::GetDefined()
{
return a;
}
In another .cpp:
int size = (define.GetDefined()).GetCount();
This does return the right value of int. But is this the correct example of assigning by reference?
Yes, although the extra braces in the final .cpp file are unnecessary and are not helpful to the reader so you should probably not bother
eg.
int size = define.GetDefined().GetCount();
You should probably also mention that the user should be sure that the object being returned by referance is not allocated on some part of the stack that is about to become invalid.
for example:
A& method() {
return A();
}
or any part of memory that is about to become invalid for that matter:
class A{
B member;
B& get_b_ref() {
return member;
}
}
int main() {
A* a_ptr = new A();
B& b_ref = a_ptr->get_b_ref();
delete a_ptr;
b_ref.any_method(); // yikes
}
Yes, it's absolutely correct to return reference from the getter.
You might even want to return const Array &, if this object should not be modified from outside
how can I convert any object of my own class convert into pointer to void?
MyClass obj;
(void*)obj; // Fail
MyClass obj;
void *p;
p = (void*)&obj; // Explicit cast.
// or:
p = &obj; // Implicit cast, as every pointer is compatible with void *
But beware ! obj is allocated on the stack this way, as soon as you leave the function the pointer becomes invalid.
Edit: Updated to show that in this case an explicit cast is not necessary since every pointer is compatible with a void pointer.
You cant convert a non-pointer to void*. You need to convert the pointer to your object to void*
(void*)(&obj); //no need to cast explicitly.
that conversion is implicit
void* p = &obj; //OK
If you use the address, you can convert it to a void pointer.
MyClass obj;
void *ptr = (void*)&obj; // Success!
To do something which has any chance of being meaningful, first you have to take the address of an object, obtaining a pointer value; then cast the pointer.
MyClass obj;
MyClass * pObj = &obj;
void * pVoidObj = (void*)pObj;
i beleive you could only convert a pointer to an object to a pointer to void ???
Perhaps: (void*)(&obj)
In addition to the technical answers: Assert, that you avoid multiple inheritance or else you don't assign the address of super-class interfaces to a void*, for they will not be unique! E.g.
class S1 { int u; };
class S2 { int v; };
class MyClass : public S1, public S2 {};
MyClass obj;
S2* s2 = &obj;
void * p1 = &obj;
void * p2 = s2;
Here p1 and p2 (==s2) will be different, because the S2 instance in C has an address offset.