Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I would like to cast a pointer to an instance of MyClass to an int*, preferably in such a way that I can do this:
void function(int*) {...};
MyClass * instance = new MyClass;
function(instance);
The int pointer should NOT be a binary copy of the MyClass pointer. Currently, I am using the following code to acheive a similar result:
int * MyClass::getIntPointer() {return &my_int;}
How do I cast a MyClass* to an int*?
Are you trying to access an int member of your class? If so, you can do this:
class MyClass {
public:
int myInt;
};
void function(int*) {...};
MyClass* instance = new MyClass;
function(&instance->myInt);
You don't want to cast MyClass to an int, you just want to access the member of MyClass.
So here's what that line means:
instance-> // follow the pointer to the actual MyClass object.
instance->myInt // access the int, "myInt"
&instance->myInt // get the address of that int
function(&instance->myInt); // call "function", passing to it the address of "myInt"
EDIT:
If you're creating a class that wraps an int, you can do this with a custom casting operator, as #cmbasnett suggests:
class MyClass {
public:
int* operator int*() { return &my_int; }
private:
int my_int;
};
MyClass instance;
function(instance); // this line will trigger the custom cast operator.
Maybe either of these strike your fancy:
#include <iostream>
struct MyClass
{
int myInt;
operator int*()
{
return &myInt;
}
};
int main()
{
MyClass* instance = new MyClass();
//method 1
instance->myInt = 42;
int* a = &(instance->myInt);
//method 2
int* b = *instance;
std::cout << *a << std::endl;
std::cout << *b << std::endl;
}
Sorry, you're stuck. You cannot overload the typecast operator for a pointer type. This is the only way you could cast from MyClass* directly to int* and require the resulting int* to point at the first int member, even if the class' storage is non-POD.
If you could guarantee that MyClass was always a POD type, then reinterpret_cast<int*>(instance) would be sufficient. But your demand that "The int pointer should NOT be a binary copy of the MyClass pointer" implies that there is no such guarantee.
If you were willing to start with a MyClass& instead of a MyClass*, then you could use cmbasnett's example of adding a typecast overload to the class.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to return a const reference so I cannot change the object itself but I can call their non-const methods. But I don't know how to do it.
With pointers is easy, I can choose between a const pointer (const myclass*) or a pointer to const values (myclass const*). But with references it seems not working the same way, all I've got it is a reference to a const object so I cannot call non-const methods.
I'm sure I'm doing something wrong.
class A {
int a;
public:
auto get() const { return a; }
auto set(int i) -> void { a = i; }
};
class B {
A a_;
public:
auto get() const -> const A& { return a_; }
};
I can do:
B b;
cout << b.get().get();
But not:
B b;
b.get().set(100); // compiler error
I don't want
class B {
A a_;
public:
auto get() -> A& { return a_; }
};
B b;
A a;
b.get() = a; // I don't want this!
You can't have "partial mutability" in that way, not without removing assignment completely from A.
(Despite your claim that this is easy with pointers, that situation is exactly the same - you need to either disallow b.get()->set(100) or allow *b.get() = a.)
One thing you can do is add a level of indirection by way of a proxy object:
class A_Setter
{
public:
A_Setter(A* a): the_a(a) {}
A_Setter& operator=(const A_Setter&) = delete;
void set(int x) { the_a->set(x); }
private:
A* the_a;
};
class B {
A a_;
public:
A_setter get() { return A_setter(&a_); }
};
Now b.get().set(100); will compile, not b.get() = a;.
Problems returning a const reference (no a reference to a const)
There is technically no such thing as const reference. References do not have top level cv-qualifiers. Const reference colloquially means a reference to const.
I want to return a ... reference so I cannot change the object itself
Objects cannot be modified through references to const, so that would work.
... but I [want to] call their non-const methods.
Non-const member functions can be called only through references to non-const. There is no category of reference that can satisfy both of your wants. They are contradictory.
With pointers is easy, I can choose between a const pointer (const myclass*) or a pointer to const values (myclass const*).
Those do not achieve what you want either. You can modify the pointed object through a const pointer (to non-const), and you cannot call const member functions of the pointed object through a (non-const) pointer to const. Neither achieves your both wants.
P.S. Returning a const (or volatile) qualified pointer - or any other built-in type - is meaningless because function calls to such function are prvalue expressions and prvalues of non-class types do not have cv-qualifiers, so the qualifiers of such return type would always be ignored. This is not to be confused with returning pointer to cv-qualified types which is meaningful.
This question already has answers here:
How do I create and use a class arrow operator? [duplicate]
(4 answers)
Closed 4 years ago.
I have gone through the smart pointer implementation. In the below program:
#include <iostream>
using namespace std;
class Car{
public:
void Run(){
cout<<"Car Running..."<<"\n";
}
};
class CarSP{
Car * sp;
public:
//Initialize Car pointer when Car
//object is createdy dynamically
CarSP(Car * cptr):sp(cptr)
{
}
// Smart pointer destructor that will de-allocate
//The memory allocated by Car class.
~CarSP(){
printf("Deleting dynamically allocated car object\n");
delete sp;
}
//Overload -> operator that will be used to
//call functions of class car
Car* operator-> ()
{
return sp;
}
};
//Test
int main(){
//Create car object and initialize to smart pointer
CarSP ptr(new Car());
ptr.Run();
//Memory allocated for car will be deleted
//Once it goes out of scope.
return 0;
}
This program is working fine with:
CarSP ptr(new Car());
ptr->Run();
But ptr is not a pointer its object of the class CarSP Now my doubt is how -> is used for accessing Car member function with this. If i am using ptr.Run();
But its giving error,
Please help.
Since I cannot include a code example in a comment, I'm adding it here as an "answer", but this is not a proper answer. See patatahooligan's link to the other Stack Overflow Q&A for a detailed explanation.
Here is a contrived example for illustrative purposes:
#include <iostream>
static char const* hello = "hello";
struct Foo
{
char const* something() const { return hello; }
};
struct Bar
{
Foo foo;
Foo const* operator->() const { return &foo; }
};
struct Quux
{
Bar bar;
Bar const& operator->() const { return bar; }
};
struct Baz
{
Quux quux;
Quux const& operator->() const { return quux; }
};
struct Corge
{
Baz baz;
Baz const& operator->() const { return baz; }
};
int main()
{
Corge corge;
// The -> resolves to a Foo const*, then called something() method.
char const* s = corge->something();
std::cout << "Result is: " << s << std::endl;
}
ptr->Run();
so C++ defines a->b to be (*a).b if and only if a is a pointer.
In this case, ptr is not a pointer. When a is not a pointer, it defines it to be:
(ptr.operator->())->b
in this case, ptr is a class type that has an operator->. That operator-> returns a pointer to Car.
So we have
(some pointer to Car)->b
and we recursively apply the C++ rule for ->. And as a pointer to car can be ->Run()'d, it works.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
class SomeClass {
int someNum;
const int someConst;
public:
SomeClass() : someNum(12), someConst(15)
{
}
SomeClass operator+(int num) {
SomeClass newSomeClass;
newSomeClass.someNum += num;
return newSomeClass;
}
};
int main() {
SomeClass someClass;
SomeClass newClass;
newClass = someClass + 3;
}
I don't understand why the above doesn't compile, but does so when the const related code is removed.
The problem is here:
SomeClass newClass;
newClass = someClass + 3;
With the first instruction you create the object newClass and the member variable is initialized:
[...] someNum(12), someConst(15) [...]
With the second instruction you're trying to assign a new object constructed by the operator+ to the object.
So actually you're trying to modify the object itself which has a const variable member.
C++ provides a default assignment operator:
newClass = someClass + 3;
means "copy all variable mambers in the object on the right side of the = in the object in the left side".
In that case the variable someConst is declared as constant value, so you cannot overwrite its value. Indeed the operation make a compile error.
Solution
In order to handle this "problem" you need to write a custom assignment operator.
That's an example:
class SomeClass {
int someNum;
const int someConst;
public:
SomeClass() : someNum(12), someConst(15)
{
}
SomeClass operator+(int num) {
SomeClass newSomeClass;
newSomeClass.someNum += num;
return newSomeClass;
}
// Custom assignment operator
SomeClass& operator=(const SomeClass& oth) {
if (this != &oth) {
this->someNum = oth.someNum;
}
return *this;
}
};
In that way you're telling to copy from an object just the member variable someNum and to avoid the cost member.
This question already has answers here:
What are the pointer-to-member operators ->* and .* in C++?
(7 answers)
Closed 7 years ago.
Good day,
I've come across this question, but I'm specifically interested in the "object pointed to by member ..." type operators as listed here on Wikipedia.
I have never seen this in the context of actual code, so the concept appears somewhat esoteric to me.
My intuition says they should be used as follows:
struct A
{
int *p;
};
int main()
{
{
A *a = new A();
a->p = new int(0);
// if this did compile, how would it be different from *a->p=5; ??
a->*p = 5;
}
{
A a;
a.p = new int(0);
// if this did compile, how would it be different from *a.p=5; ??
a.*p = 5;
}
return 0;
}
But this doesn't compile because p is undeclared. (See example)
Could anyone please provide a real-world example of the use of operator->* and/or .* in C++?
Those operators are used for pointer-to-member objects. You won't come across them very often. They can be used to specify what function or member data to use for a given algorithm operating on A objects, for instance.
Basic syntax:
#include <iostream>
struct A
{
int i;
int geti() {return i;}
A():i{3}{}
};
int main()
{
{
A a;
int A::*ai_ptr = &A::i; //pointer to member data
std::cout << a.*ai_ptr; //access through p-t-m
}
{
A* a = new A{};
int (A::*ai_func)() = &A::geti; //pointer to member function
std::cout << (a->*ai_func)(); //access through p-t-m-f
}
return 0;
}
The ->* and .* syntax is the "pointer-to-member" operator that can be used to store pointers to members of a very specific object.
Usage example:
class A {
public: int x;
};
int main() {
A obj;
int A::* memberPointer = &A::b; //Pointer to b, which is int, which is member of A
obj.*memberPointer = 42; //Set the value via an object
A *objPtr = &obj;
objPtr->*memberPointer = 21; //Set the value via an object pointer
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The C++ draft says that
A non-type template-parameter shall have one of the following
(optionally cv-qualified) types: — integral or enumeration type, —
pointer to object or pointer to function, — lvalue reference to object
or lvalue reference to function, — pointer to member, —
std::nullptr_t.
In the following code I have a pointer to member passed as parameter to a template
using namespace std;
class MyClass
{
public:
int membervar;
};
template< int (MyClass::*var) > struct A
{
// What am I supposed to do with *var? There isn't an object instance to use it!
};
int main(int argc, char *argv[])
{
struct A <&MyClass::membervar> object;
}
The above code compiles (MSVC2012) without errors
The question is: I don't see what am I supposed to do with such a pointer, there isn't an object instance to use it
The only way I can think to answer this is to construct an example:
template< int (MyClass::*var) > struct A
{
A() {
MyClass myclass;
myclass.*var = 42;
cout << myclass.*var << "\n";
}
};
You use it as a regular pointer-to-member:
template< int (MyClass::*var) > struct A
{
void foo()
{
MyClass Blah;
Blah.*var = 3;
}
};
Nothing prevents A from having methods taking MyClass as parameters though:
template <int (MyClass::*var)>
struct A {
int get(MyClass const& mc) const { return mc.*var; }
void set(MyClass& mc, int i) { mc.*var = i; }
};
int main() {
MyClass mc;
A<&MyClass::membervar> a;
a.set(mc, 3);
std::cout << a.get(mc) << "\n"; // prints 3
}