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;
}
Related
We use dynamic_cast operator to safely convert a pointer or a reference to a base type into a pointer or a reference to a derived type.
struct Foo{
void f() const{
std::cout << "Foo::f()\n";
}
virtual ~Foo() = default;
};
struct Bar : Foo{
void f() const {
std::cout << "Bar::f()\n";
}
};
int main(){
Foo* pf = new Foo{};
Bar* pb = dynamic_cast<Bar*>(pf);
if(pb)
pb->f();
delete pf;
pf = new Bar{};
pb = dynamic_cast<Bar*>(pf);
if(pb)
pb->f();
delete pf;
Bar b{};
Foo& rf = b;
Bar& rb = dynamic_cast<Bar&>(rf);
// if(rb) // ?
rb.f();
}
So how to check whether dynamic_cast returns a valid or invalid reference? - For a pointer it is OK as long as we compare the pointer against nullptr value but for a reference how?
Intended as a placeholder for the comment by #1201ProgramAlarm.
Simply put,
A failed dynamic cast for a reference throws an exception. – 1201ProgramAlarm
From the IBM docs:
You cannot verify the success of a dynamic cast using reference types by comparing the result (the reference that results from the dynamic cast) with zero because there is no such thing as a zero reference. A failing dynamic cast to a reference type throws a bad_cast exception.
So to verify the cast succeeded, just make sure it didn't throw an exception.
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)
Assume I have a class with different constructors:
class A
{
public:
A(char* string)
{
//...
}
A(int value)
{
//..
}
void check() {}
};
Now I want to create an A object on stack, the constructor must be choosed depending on some condition, but there is a problem: the created object is destroyed then we quit {...} block.
bool isTrue() { /*...*/ }
int main()
{
if (isTrue())
{
A a("string");
}
else
{
A a(10);
}
a.check(); //error: 'a' is not defined in this scope
}
Suppose I haven't the copy-constructor or operator= in the A class. So how can solve this issue?
http://ideone.com/YsjmnK
A a = isTrue() ? A("string") : A(10);
And if a.check() is a const member function, an alternative may be better:
const A& a = isTrue() ? A("string") : A(10);
The object will be destroyed when the reference a go out of scope.
Note since C++17, according to the rule of copy elision the copy/move constructor is not required to be accessible for this case; copy elision is guaranteed here.
And since C++17 you can use std::optional, which doesn't cause any dynamic memory allocation. e.g.
std::optional<A> a;
if (isTrue())
{
a.emplace("string");
}
else
{
a.emplace(10);
}
(*a).check();
BTW: A(char* string) is supposed to be A(const char* string).
You can't satisfy all your stated requirements.
If you can get rid of the requirement for the object to be on stack, you could use a pointer.
A *a;
if (isTrue())
a = new A("string");
else
a = new A(10);
a->check();
delete a;
If the type has a default constructor, you can default-construct an object, immediately destruct it, and then construct it again with the appropriate constructor via placement-new:
A a;
a.~A();
if (isTrue())
{
new(&a) A("string");
}
else
{
new(&a) A(10);
}
The C++ standard has several examples similar to the above, just search for .~ and ->~.
Note that this is ultra evil. If your code ever gets reviewed, you are probably going to get fired.
I had the exact same question a while ago and this is what google helped me find:
unique_ptr<A> foo;
if(isTrue())
foo = std::unique_ptr<A>(new A("10"));
else
foo = std::unique_ptr<A>(new A(10));
Its probably too late for the OP but someone else might hopefully find this useful.
You can use the template class:
template<class type> class A
{
protected:
type T;
public:
void A(type t_curr) {T = t_curr;};//e.g.---
void check() {}
};
Is it possible to cast from a predefined Type_pointer in c++ to its Type?
For example we defined a custom XType.
I want to do something like this, but I get an error:
XType* b;
XType a = (XType) b;
I want to pass the pointer itself to a function that only accept Type (not Type*)
You should dereference the pointer with the * operator:
struct Type {
Type(Type*) {}
};
void f(Type t) {
}
int main () {
Type a;
Type* b = &a;
// Q: how to invoke f() if I only have b?
// A: With the dereference operator
f(*b);
}
In addition to the #Robᵩ's proposal, you can change the function to accept the pointer.
Actually, if you plan to pass the pointer to other functions from within the given function, you must get the pointer (well, or a reference) as parameter, otherwise you'll get a copy of the original object as the parameter, so you'll be unable to retrieve the address of (i.e. pointer to) the original object.
If you'd like to spare the refactoring, you can do the reference trick:
void g(T* pt)
{
// ...
}
void f(T& rt) // was: void f(T rt)
{
cout << rt.x << endl; // no need to change, syntax of ref access
// is the same as value access
g(&rt); // here you get the pointer to the original t
}
T* t = new T();
f(t);
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