C++ When do I use -> or :: - c++

I know that in C++, you use either -> or :: instead of . in language such as C# to access object's values, e.g. button->Text or System::String^, but I don't know when I should use -> or ::, and it is very frustrating as it causes me many compiler errors. I would be very grateful if you could help. Thanks :)

-> is when you are accessing the member of a pointer variable. EG: myclass *m = new myclass(); m->myfunc(); Calls myfunc() on pointer to myclass. :: is the scoping operator. This is to show what scope something is in. So if myclass is in namespace foo then you'd write foo::myclass mc;

-> if you have pointer to some object this is just shortcut for dereferencing that pointer and accessing its attribute.
pointerToObject->member is the same as (*pointerToObject).member
:: Is for access stuff from some scope - it works only on namespaces and class/struct scopes.
namespace MyNamespace {
typedef int MyInt;
}
MyNamespace::MyInt variable;

Contrary to what your question states, you do use . in C++. Quite a bit.
. (used with non-pointers to access members and methods)
std::string hello = "Hello";
if (hello.length() > 3) { ... }
-> (used with pointers to access members and methods)
MyClass *myObject = new MyClass;
if (myObject->property)
myObject->method();
:: (scope resolution)
void MyClass::method() { ... } //Define method outside of class body
MyClass::static_property; //access static properties / methods
:: is also used for namespace resolution (see first example, std::string, where string is in the namespace std).

I try to show an examples of some usages of ::, . and ->. I hope it helps:
int g;
namespace test
{
struct Test
{
int x;
static void func();
};
void Test:: func() {
int g = ::g;
}
}
int main() {
test::Test v;
test::Test *p = &v;
v.x = 1;
v.func();
p->x = 2;
p->func();
test::Test::func();
}

Opertor -> is applied when the left operand is a pointer. Consider for example
struct A
{
int a, b;
A( int a, int b ) : a( a ), b( this->a * b ) {}
};
Operator :: referes to the class or anmespace for which the right operand belongs. For example
int a;
strunt A
{
int a;
A( int a ) { A::a = a + ::a; }
};
The period is used then the left operand is lvalue of an object. For example
struct A
{
int x;
int y;
};
A *a = new A;
a->x = 10;
( *a ).y = 20;

Related

Initialize parameter into constructor, other than the first one

I want to explicitly change the second parameter in a constructor of a struct, in the following scenario. Is it possible, if so, how?
struct foo{
int x;
int y;
foo(int a=4, int b=6){
x=a;
y=b;
}
};
int main(){
foo *f = new foo();
cout<<f->x<<" "<<f->y<<endl;
//4 6
foo *g = new foo(3,4);
cout<<g->x<<" "<<g->y<<endl;
//3 4
foo *h = new foo(3);
cout<<h->x<<" "<<h->y<<endl;
//3 6
//Can something like this be
//done in C++, if I want
//to change the value of the
//second variable only
foo *k = new foo(b = 13);
return 0;
}
Is it possible, if so, how?
It is not possible with constructor. In general, c++ does not support named keyword arguments to functions, and it is not possible to skip arguments even if they have a default, if you want to pass a non-default after it.
It will be possible without constructor using list initialisation syntax since C++20 using designated initialisers, if you use default member initialisers:
struct foo{
int x = 4;
int y = 6;
};
int main(){
foo f {.y = 4};
}
You can achieve something similar with tag dispatching; No need for future standard:
struct foo{
int x = 4;
int y = 6;
enum Xtag { Xinit };
enum Ytag { Yinit };
foo(int a, int b) : x(a), y(b) {}
foo(Xtag, int a) : x(a) {}
foo(Ytag, int b) : y(b) {}
};
int main(){
foo f(foo::Yinit, 4);
}
A solution using lambda that can be used without modifying an existing class. Following works with your definition of foo:
auto make_foo_x4 = [](int b) {
return foo(4, b);
};
foo f = make_foo_y(4);
The downside is that we have to explicitly repeat the default value of x, so this can break assumptions if the default is changed in class definition.

C++ operator ->* and .* [duplicate]

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
}

C++ assigning method in constructor using pointers to other methods: what am I doing wrong?

I wrote the following code:
#include <iostream>
using namespace std ;
class C{
public:
C::C(int) ;
int f1(int);
int f2(int);
int (*f)(int);
}
int C::f1(int x){
return -x ;
}
int C::f2(int x){
return x;
}
C::C(int c){
if (c<0){
f = f1 ;
}
else {
f = f2 ;
}
}
This code doesn't work, but the idea is that I want the method f to be assigned either to f1 or to f2 depending on the value passed to the constructor.
How can I achieve this in C++?
If your member functions are non-static, then you have to declare f as a member function pointer:
int (C::*f)(int);
Given the name m of a member function of class C, you get member function pointers to m by writing:
&C::m
In your case:
if (c<0){
f = &C::f1;
}
else {
f = &C::f2;
}
Here is a live example with the full code.
Invoking your member function through the pointer-to-member f will then require the use of operator ->* or .*. For instance:
int main()
{
C c(42);
(c.*(c.f))(1729);
int (C::*fxn)(int) = c.f;
(c.*fxn)(0);
C* p = &c;
(p->*fxn)(123);
}
Or, from inside a given member function fxn of C:
void C::fxn()
{
// ...
(this->*f)(6);
}
On the other hand, if your functions f1() and f() do not need to work on a specific instance of C, you could leave the declaration of f as is as well as the code in C's constructor, but you would have to mark f1() and f2() as static:
class C
{
public:
C(int);
static int f1(int);
// ^^^^^^
static int f2(int);
// ^^^^^^
int (*f)(int);
};
You can normally do this but you need to mark f1 and f2 as static. Otherwise they need a this pointer which normally can't be stored in the function pointer.
class C
{
public:
C(int);
static int f1(int);
static int f2(int);
int (*f) (int);
};
int C::f1(int x)
{
return -x;
}
int C::f2(int x)
{
return x;
}
C::C(int c)
{
if (c < 0) {
f = f1;
} else {
f = f2;
}
}

Pointer Wrapper: dereference operator

I'm pretty new to C++ and as an exercise (and perhaps eventually .Net utility) I'm doing a pointer wrapper (actually in C++/CLI, but this applies to C++ as well). This pointer wrapper (called Apont) currently behaves just like a pointer would, as the test below can show, if lines marked 1. and 2. are commented out:
int main(array<System::String ^> ^args)
{
double ia = 10; double ip = 10;
double *p = &ip; // pointer analogy
Apont<double> ^a =
gcnew Apont<double>(ia); // equivalent to what's below, without errors
a = ~ia;/* 1. IntelliSense: expression must have integral or unscoped enum type
error C2440: '=' : cannot convert from 'double' to 'Utilidades::ComNativos::Apont<T> ^'
error C2171: '~' : illegal on operands of type 'double'*/
Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
ia = 20; ip = 20;
Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
*p = 30; // pointer analogy
a->Valor = 30; // does exacly what's below, without errors
!a = 30;/* 2. IntelliSense: expression must be a modifiable lvalue
error C2106: '=' : left operand must be l-value */
Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
//a->Dispose();
Console::ReadKey();
p = nullptr;
return 0;
}
There are two things I don't like here, marked with 1. and 2. in the code comments, before the lines with errors. The operator~ (see 1.) is defined outside Apont, below:
template<typename T> static Apont<T>^% operator ~(T& valor)
{
return gcnew Apont<T>(valor);
}
I think this one has to be defined outside Apont, but I'm not sure. I cannot understand very well the errors it produces (these are, of course, in the use, not in the definition).
To set the value to which the instance of Apont refers I must use a property (the line marked 2. doesn't work, with errors in the setting usage only), Apont::Valor, which is the equivalent to use *p. What I'd like to do is as I use *p to get or set the value it points to, use !a with the same effect on Apont. Here's Apont::operator!()'s current definition:
T operator !()
{
return Valor;
}
As you can see in 2. (comment in the code, before the respective errors), it doesn't work for setting a value. Maybe I should return a reference? Make another operator with the same name, perhaps outside the class? I tried several options, however, I got similar errors, and came out more confused.
The question is: how can I make an operator that behaves like & (in this case, ~) and one that behaves like * (in this case, !, for dereference, but that behaves like Apont::Valor, whose old definition you can see below)?
property T Valor
{
T get()
{
if (pointer != nullptr)
return *pointer;
else if (eliminado && ErroSeEliminado) // means "disposed && ErrorIfDisposed"
throw gcnew ObjectDisposedException("O objeto já foi pelo menos parcialmente eliminadao.");
else if (ErroSeNulo) // means "ErrorIfNull"
throw gcnew NullReferenceException();
else
return 0;
// don't worry, this is not default behavior, it is returned only if you want to ignore all errors and if the pointer is null
}
void set(T valor)
{
*pointer = valor;
}
}
Let me recap in a new answer for clarity.
Solving the ! operator is easy, as I said in my previous answer, just add a reference.
So for the operator ~, the goal was to have it behave like the & operator and call the constructor of the pointer wrapper class.
I don't think that is possible. It is certainly possible for user defined objects, but I don't think it is possible to overload unary operators for builtin types. So there are three solutions depending on what you prefer:
The first one does exactly what you want, but will break for primitive types:
#include <iostream>
template<typename T>
struct A {
T* payload;
A()
: payload(NULL){}
A(T *ptr)
: payload(ptr) {}
T& operator !(){
return *payload;
}
};
// this will not work for primary types
template<typename T>
A<T> operator ~(T &b){
return A<T>(&b);
}
struct B{
int test;
};
int main(){
B b; b.test = 4;
A<B> a;
a = ~b; // I think this is what you want
std::cerr << (!a).test << std::endl;
// this does not work
//int i = 4;
//A<int> a;
//a = ~i;
}
Second solution: use a compound assignment operator. Pros are the side effects are minimal, cons is this is not very intuitive and might break the nice design you had in mind.
#include <iostream>
template<typename T>
struct A {
T* payload;
A() : payload(NULL){}
T& operator !(){
return *payload;
}
};
template<typename T>
A<T>& operator &=(A<T> &a, T& b){ // should be friend of the above
a.payload = &b;
return a;
}
int main(){
int i = 3;
A<int> a;
a &= i;
std::cerr << !a << std::endl;
}
Third solution: overload the basic assignment operator. This is more intuitive to write but has a lot of side effects:
#include <iostream>
template<typename T>
struct A {
T* payload;
A() : payload(NULL){}
T& operator !(){
return *payload;
}
A<T>& operator = (T & b) {
payload = &b;
return *this;
}
};
int main(){
int i = 3;
A<int> a;
a = i;
std::cerr << !a << std::endl;
}
Someone might have a solution to hijack the operators for primitive types, but i can't think of any simple solution.
If i understood your code correctly, you want the operator ~ to return a copy of the pointer wrapper and the operator ! to act as dereference?
In this case, you can define the unary operator ~ inside the Apont class which calls a copy constructor. And the operator ! has to return a reference indeed if you want to asign a value.
I think the following c++ code defines what you want to do (I renamed Apont to A):
#include <iostream>
template<typename T>
struct A {
T* payload;
A(T *ptr)
:payload(ptr) {}
A(const A&other)
:payload(other.payload) {}
T& operator !(){
return *payload;
}
T* operator ~(){
return payload;
}
};
int main(){
#define PRINT(X) std::cerr << #X << " = " << X << std::endl
int i = 0;
PRINT(i);
A<int> a(&i);
!a = 1;
PRINT(i);
A<int> b = ~a;
!b = 2;
PRINT(i);
}
The output of the code above is:
i = 0
i = 1
i = 2
According to your comments, you said you wanted the operator ! to behave exactly like the wrapped pointer. You can do so, but then the syntax changes and you need to dereference it to assign a new value (because it is a pointer...). ie something like:
#include <iostream>
template<typename T>
struct A {
T* payload;
A(T *ptr): payload(ptr) {}
// this now behaves like accessing the wrapped pointer directly
T*& operator !(){
return payload;
}
};
int main(){
#define PRINT(X) std::cerr << #X << " = " << X << std::endl
int i = 0;
int j = 999;
PRINT(i);
A<int> a(&i);
*(!a) = 1; // note the change of syntax here
PRINT(*!a); // and here
!a = &j; // but now you can change the wrapped pointer through the operator
PRINT(*!a);
}

Scope of variables in if statements

I have a class that has no default constructor or assignment operator so it is declared and initialized within an if/else statement depending on the result of another function. But then it says that it is out of scope later even though both routes of the conditional will create an instance.
Consider the following example (done with int just to illustrate the point):
#include <iostream>
int main()
{
if(1) {
int i = 5;
} else {
int i = 0;
}
std::cout << i << std::endl;
return 0;
}
Do variables declared in a conditional go out of scope at the end of the conditional? What is the correct way to handle the situation where there is no default constructor but the arguments for the constructor depend on certain conditionals?
Edit
In light of the answers given, the situation is more complex so maybe the approach would have to change. There is an abstract base class A and two classes B and C that derive from A. How would something like this:
if(condition) {
B obj(args);
} else {
C obj(args);
}
change the approach? Since A is abstract, I couldn't just declare A* obj and create the appropriate type with new.
"Do variables declared in a conditional go out of scope at the end of the conditional?"
Yes - the scope of a local variable only falls within enclosing brackets:
{
int x; //scope begins
//...
}//scope ends
//x is not available here
In your case, say you have class A.
If you're not dealing with pointers:
A a( condition ? 1 : 2 );
or if you're using a different constructor prototype:
A a = condition ? A(1) : A(2,3);
If you're creating the instance on the heap:
A* instance = NULL;
if ( condition )
{
instance = new A(1);
}
else
{
instance = new A(2);
}
or you could use the ternary operator:
//if condition is true, call A(1), otherwise A(2)
A* instance = new A( condition ? 1 : 2 );
EDIT:
Yes you could:
A* x = NULL; //pointer to abstract class - it works
if ( condition )
x = new B();
else
x = new C();
EDIT:
It seems what you're looking for is the factory pattern (look it up):
class A; //abstract
class B : public A;
class C : public A;
class AFactory
{
public:
A* create(int x)
{
if ( x == 0 )
return new B;
if ( x == 1 )
return new C;
return NULL;
}
};
Do variables declared in a conditional go out of scope at the end of
the conditional?
Yes.
What is the correct way to handle the situation where there is no
default constructor but the arguments for the constructor depend on
certain conditionals?
Write a function that returns a value, from which you copy.
T foo()
{
if(condition)
return T(x);
return T(y);
}
void bar()
{
T i(foo());
}
Edit:
Since A is abstract, I couldn't just declare A* obj and create the
appropriate type with new.
What do you mean? That's exactly how dynamic typing works. Except I wouldn't use a raw pointer, I would use a unique_ptr.
std::unique_ptr<A> obj;
if(condition) {
obj = std::unique_ptr<A>(new B(args));
} else {
obj = std::unique_ptr<A>(new C(args));
}
Your alternative will be pointers:
MyObject *obj;
if(cond1)
{
obj = new MyObject(1, 2, 3);
}
else
{
obj = new MyObject(4, 5);
}
Remember to delete it when you are done with it, or use a smart pointer.
Yes it will be out of scope if declared in a conditional, loop etc. Will the type of the variable change depending on the conditional?