I need to pass to function pointer to int.
Now if I want to pass 5 I'm doing it like this:
int * i = NULL;
int b = 5;
i = &b;
Is there any better way to write it shorter?
I want to pass bytes that are in i int to this function:
void Write2Asm(void* pxAddress, BYTE * MyBytes, int size)
You can just pass &b to the function; no need for an intermediate pointer variable.
Why to create a pointer variable?. Why can't you do it like this?.
int b = 5;
func(&b)
void f(int *i)
{
//...
}
int b = 5;
f(&b);
is enough!
There are a few old C APIs that always take arguments by pointer, even if they're effectively read-only booleans etc.. I'm not recommending it - more for interest's sake - but if you want to go the whole hog you could do something hackish like:
#include <iostream>
struct X
{
X(int n) : n_(n) { std::cout << "X()\n"; }
~X() { std::cout << "~X()\n"; }
operator int&() { return n_; }
operator const int() const { return n_; }
int* operator&() { return &n_; }
const int* operator&() const { return &n_; }
int n_;
};
// for a function that modifies arguments like this you'd typically
// want to use the modified values afterwards, so wouldn't use
// temporaries in the caller, but just to prove this more difficult
// case is also possible and safe...
void f(int* p1, int* p2)
{
std::cout << "> f(&" << *p1 << ", &" << *p2 << ")\n";
*p1 += *p2;
*p2 += *p1;
std::cout << "< f() &" << *p1 << ", &" << *p2 << "\n";
}
int main()
{
// usage...
f(&X(5), &X(7));
std::cout << "post\n";
}
Crucially, the temporaries are valid until after the function call f(...) exits.
Related
Take a look at this simple array class
class Array {
const unsigned int _size;
int _array[100];
public:
Array() : _size(100) {
for(unsigned int i = 0; i < _size; i++)
_array[i] = 0;
}
int& operator[](unsigned int index) {
cout << "normal operator[].\n";
return _array[index];
}
const int& operator[](unsigned int index) const {
cout << "const operator[].\n";
return _array[index];
}
};
int main()
{
Array a;
a[3] = 1;
cout << a[3] << "\n";
system("pause");
return 0;
}
The "normal operator[]" line is executed twice, though I would expect the second call (cout << a[3] << "\n";) to be using the const version of the overloaded operator, because it doesn't change the array itself.
Why is that? Is there a way to force the const version to be called as I wish?
When you have an overloaded const version of a method, the const version will be called when the object is const. For example:
#include <iostream>
using namespace std;
class MyClass
{
public:
void foo()
{
cout << "foo()" << endl;
}
void foo() const
{
cout << "foo() const" << endl;
}
};
int main()
{
MyClass a;
const MyClass b;
a.foo();
b.foo();
return 0;
}
will call the normal foo() for the object a, and the const version for the object b.
In your case, you just have to avoid trying to assign to the const version. For example:
Array a;
const Array b;
a[3] = 1;
// b[3] = 1; // error
cout << a[3] << "\n";
cout << b[3] << "\n";
works fine. But if you try to make the assignment to b, you get a compile error.
std::ostream &operator<<(int x) doesn't take its parameter as const (because const isn't useful when passing by value), so the non-const operator[] can be called.
So, when will const operator[] be called?
It is true that a const vector variable declaration is almost always useless aside from some edge cases. The primary reason const operator[] is important, and the most often you will see it used, is calling it on a reference parameter.
int readStuff(const std::vector<int> &dontMutateMe) {
return dontMutateMe[42]; // const
}
Constant reference parameters are valuable, and this code wouldn't work without const operator[].
I'm wondering if it's by chance a pointer to const reference bound to a destroyed stack variable can be working.
I read const reference lifetime is extended on rvalues, so this is "normal" const reference works but at the end of the ctor of Storage ref should be destroyed, isn't it ?
Does const reference lifetime is also extended because I retrieved it's address in a pointer or is this pure luck ?
Live example
#include <iostream>
class Storage
{
public:
Storage(const int& ref)
{
p = &ref;
}
const int* Get() const
{
return p;
}
private:
const int* p;
};
int main()
{
Storage* s = nullptr;
{
int someValue = 42;
std::cout << &someValue << std::endl;
s = new Storage(someValue);
}
const int* p = s->Get();
std::cout << p << std::endl;
std::cout << *p << std::endl;
}
It's also working with a struct Live example
#include <iostream>
struct Dummy
{
int value;
};
class Storage
{
public:
Storage(const Dummy& ref)
{
p = &ref; // Get address of const reference
}
const Dummy* Get() const
{
return p;
}
private:
const Dummy* p;
};
int main()
{
Storage* s = nullptr;
{
Dummy dummy;
dummy.value = 42;
std::cout << &dummy << std::endl;
s = new Storage(dummy);
}
const Dummy* p = s->Get();
std::cout << p << std::endl;
std::cout << p->value << std::endl;
}
Your s variable indeed has a dangling pointer as someValue has fallen out of scope. Your code therefore exhibits undefined behavior.
Your comment about "const reference lifetime is extended on rvalues" is true in some circumstances, but someValue is an lvalue.
The compiler probably assigns the stack space for all the local variables at the start, so someValue is still in the same place in memory even after it goes out of scope. Of course a different compiler might do something different, and it could get overwritten by a subsequent local variable.
For your second example if you wrote a ~Dummy(){ value=0; }, then it wouldn't work, proving that the lifetime of the dummy object hasn't been extended.
I've created the class array and something is going weird.. the class is the following:
class array
{
private:
int *a_;
size_t size_;
public:
array();
array(const size_t);
array(const arreglo &);
~array();
int const &operator[](size_t)const;
int &operator[](size_t);
array const &operator=(const array&);
bool empty()const;
};
The overload's implementation of [] are:
int const &array::operator[](size_t index)const
{
std::cout << "getter" << std::endl;
return a_[index];
}
int & array::operator[](size_t index)
{
std::cout << "setter" << std::endl;
return a_[index];
}
The way i'm testing the code is in this main:
int main()
{
array a(7);
a[0] = 3;
a[1] = 6;
a[2] = a[0] + a[1];
array b = a;
std::cout << b[2] << std::endl;
return 0;
}
The problem is that the opertar [] is just using the getter version and prints through cout "setter" and never "getter".
What is going wrong?
Thinking of them as "getter" and "setter" variants is a mistake. The difference between the two is merely the cv-qualification of the function and the return type. They are both getters. More importantly, you are returning reference types.
References tend to decay, in this case to a mutable int, therefore the compiler is more likely to accept a non-const function call.
a[0];
The default evaluation of this statement is an integer value, not a reference, so that you can for instance do:
if (a[0])
and this is predicate on the value at a[0] rather than the reference (evaluating the reference would always be true and not very helpful).
Remember that when references are used in most statements they decay to the referred value.
int v = a[0]; // no error, even tho v's type is not int&
int& vr = a[0]; // decays to the value a references
// then takes a reference of that
(Note: that the compiler may elide the implied set of operations to simply capture or imply the original reference in the second statement).
So the code
a[2] = a[0] + a[1]
It starts by getting the values from a[0] and a[1], knowing that it wants to do math, so the easiest way for it to do this is:
int a1 = a.operator[](1);
int a0 = a.operator[](0);
int& dest = a.operator[](2);
dest = a0 + a1;
If you want const, you're going to need either a const/const-ref to an array or to specify that you want a const ref:
const int& ar = a[0];
#include <iostream>
struct array
{
int i = 0;
array() {}
const int &operator[](size_t) const { std::cout << "const int[]\n"; return i; }
int &operator[](size_t) { std::cout << "int[]\n"; return i; }
};
int main()
{
array a;
a[0];
int v1 = a[0];
const int v2 = a[0];
std::cout << "refs\n";
int& v3 = a[0];
const int& v4 = a[0];
std::cout << "const array\n";
const array b;
b[0];
int v5 = b[0];
const int v6 = b[0];
std::cout << "refs\n";
//int& v7 = b[0]; // would produce a compile error
const int& v8 = b[0];
}
See http://ideone.com/7EYGYj
In short
void f(const array& b){
std::cout << b[2] << std::endl;
}
b is required to be const. All that is available is the const functions.
In your example it is a "read" but b is not const so the non-const is called. It is using the "setter" as the getter.
I'm writing an accessor method for a shared pointer in C++ that goes something like this:
class Foo {
public:
return_type getBar() const {
return m_bar;
}
private:
boost::shared_ptr<Bar> m_bar;
}
So to support the const-ness of getBar() the return type should be a boost::shared_ptr that prevents modification of the Bar it points to. My guess is that shared_ptr<const Bar> is the type I want to return to do that, whereas const shared_ptr<Bar> would prevent reassignment of the pointer itself to point to a different Bar but allow modification of the Bar that it points to... However, I'm not sure. I'd appreciate it if someone who knows for sure could either confirm this, or correct me if I got it wrong. Thanks!
You are right. shared_ptr<const T> p; is similar to const T * p; (or, equivalently, T const * p;), that is, the pointed object is const whereas const shared_ptr<T> p; is similar to T* const p; which means that p is const. In summary:
shared_ptr<T> p; ---> T * p; : nothing is const
const shared_ptr<T> p; ---> T * const p; : p is const
shared_ptr<const T> p; ---> const T * p; <=> T const * p; : *p is const
const shared_ptr<const T> p; ---> const T * const p; <=> T const * const p; : p and *p are const.
The same holds for weak_ptr and unique_ptr.
I would like to a simple demostration based on #Cassio Neri's answer:
#include <memory>
int main(){
std::shared_ptr<int> i = std::make_shared<int>(1);
std::shared_ptr<int const> ci;
// i = ci; // compile error
ci = i;
std::cout << *i << "\t" << *ci << std::endl; // both will be 1
*i = 2;
std::cout << *i << "\t" << *ci << std::endl; // both will be 2
i = std::make_shared<int>(3);
std::cout << *i << "\t" << *ci << std::endl; // only *i has changed
// *ci = 20; // compile error
ci = std::make_shared<int>(5);
std::cout << *i << "\t" << *ci << std::endl; // only *ci has changed
}
boost::shared_ptr<Bar const> prevents modification of the
Bar object through the shared pointer. As a return value, the
const in boost::shared_ptr<Bar> const means that you cannot
call a non-const function on the returned temporary; if it were
for a real pointer (e.g. Bar* const), it would be completely
ignored.
In general, even here, the usual rules apply: const modifies
what precedes it: in boost::shared_ptr<Bar const>, the Bar;
in boost::shared_ptr<Bar> const, it's the instantiation (the
expression boost::shared_ptr<Bar> which is const.
#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler
#include <memory>
using namespace std;
class A {
public:
int a = 5;
};
shared_ptr<A> f1() {
const shared_ptr<A> sA(new A);
shared_ptr<A> sA2(new A);
sA = sA2; // compile-error
return sA;
}
shared_ptr<A> f2() {
shared_ptr<const A> sA(new A);
sA->a = 4; // compile-error
return sA;
}
int main(int argc, char** argv) {
f1();
f2();
return 0;
}
The code below introduces a class C. The class has constructor, copy constructor, operator= and one member. How can I get the address of the object created by C(2) in the function main()?
#include <iostream>
class C
{
public:
int a;
C(const C &other)
{
std::cout << "Copy Constructor:" << a << std::endl;
}
C(int a)
{
this->a = a;
std::cout << "Constructor:" << a << std::endl;
}
C &operator=(const C &other)
{
std::cout << "operator=:this.a = " << a << " | other.a = " << other.a << std::endl;
a = other.a;
return *this;
}
~C()
{
std::cout << "Destructor:" << a << std::endl;
}
};
int main()
{
C a(1);
a = C(2);
}
You can't. You are forbidden from taking addresses of temporaries. They will go out of scope very quickly, leaving you with an invalid address.
You could use a helper function to write the address somewhere before the object goes out of scope:
template <typename T>
T const & store_possibly_invalid_address(T const & t, T const *& p)
{
p = &t;
return t;
}
int main()
{
C a(1);
C const * invalid_address;
a = store_possibly_invalid_address(C(2), invalid_address);
// The temporary is out of scope, but you can see where it was.
// Don't dereference the pointer.
}
That could be educational, to discover where the compiler chooses to put temporaries. It has no purpose in any real code, though.
The only way is with some collaboration inside the class; the
constructor has the address (the this pointer), and can put it
somewhere where you can get at it later. I'd recommend against it,
though, since the object won't live long enough for you to do much with
it. (On the other hand, it's sometimes useful for debugging to output
it.)