What does the :: mean in C++? [duplicate] - c++

This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 6 years ago.
void weight_data::rev_seq(string &seq){
//TODO
std::reverse(seq.begin(), seq.end());
}
In this C++ method, I think this method does not return anything, so the prefix is void, what does :: tell the relationships between weight_data and rev_seq(string &seq)? Thanks!

void is the return type. :: is the scope resolution operator, so it means rev_seq is inside the scope of weight_data. weight_data could be either a namespace or a class (based on what you've given, it's not possible to say which).

In C++,
A::B means B is an identifier within either namespace or class type A,
A.B means B is a member of the struct, class, or union type an instance of which is referred to by the object or reference A, and
A->B means B is a member of the struct, class, or union type an instance of which is referred to by the pointer A. (It's equivalent to (*A).B.)
In some other languages, all three cases are covered by a . only.
Note that in C++, member function don't have to be implemented (defined) within their class' definition. (If they are, they are implicitly inline.) They can be, and often are, implemented in separate implementation (.cpp) files. This has the advantage that not all users of a class need to recompile when you change an implementation of one of the class' member functions. So unless weight_data is a namespace name, void weight_data::rev_seq(string &seq) {...} is such a definition of a class member outside of its class.

weight_data is a namespace or class name.

The line void weight_data::rev_seq(string &seq) tells the compiler that this is the definition of the rev_seq(string &seq) member function from the weight_data. If this just said void rev_seq(string &seq) { ... } the compiler would think that a non-member function was being defined, as opposed to the rev_seq(string &seq) member function of the weight_data class.
class weight_data
{
void rev_str(string &seq);
}
It can also mean that rev_str refers to a function that is part of namespace weight_data.
namespace weight_data
{
void rev_str(string &seq);
}

Just thought of adding 2 more interesting things about the ::
a) Operator :: is both a unary and a binary operator
struct A{
int m;
};
int x;
int main(){
::x; // Unary
int (A::*p) = &A::m; // Binary
}
b) $10.3/12 - "Explicit qualification with the scope operator (5.1) suppresses the virtual call mechanism."
struct A{
virtual void f(){cout << 1;}
};
struct B : A{
void f(){cout << 2;}
};
int x;
int main(){
B b;
A &ra = b;
ra.f(); // dynamic binding, prints 2
ra.A::f(); // suppress VF mechanism, prints 1.
}

Related

why declaring an object of a class before defining it gives error in friend class but not in friend function

class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// friend function declaration
friend int add(A, B);
};
this does not give any error on declaring object of class B in friend
function,,but this gives,,as firstly class B is declared
class Apple;
class B {
private:
int b;
public:
void showA(Apple d)
{
// Since B is friend of A, it can access
// private members of A
cout << "A::a=" ;
}
};
};
this gives an error of incomplete type for object d,,why this is happening though we already declared class apple before,
Why does the first example compile?
In your first example, you have a forward declaration of class B followed by a declaration of a friend function that uses it in its parameter list:
class B;
class A {
...
friend int add(A, B);
};
This is allowed because, although B is incomplete, we are not defining add yet, only declaring an intention to eventually do so.
Why does the second example not compile?
In the second example, we have a forward declaration of class Apple, followed by a definition of showA:
class Apple;
class B {
...
void showA(Apple d)
{
...
}
};
This time, since we are defining the function, the compiler is obligated to generate code for it. But because Apple is incomplete, the compiler cannot know, for example, how much space in memory to reserve to hold the parameter d. Therefore this is an error.
The question When can I use a forward declaration? explains some of what can and cannot be done with an incomplete (forward-declared) type.
The use of 'friend' is irrelevant here
The friend keyword is basically irrelevant here. friend primarily affects access control (in the sense of public and private), but that's not the issue here.
A detail: friend also affects scoping. Because of friend, add is not a member of class A, but rather refers to a member of the global scope without actually introducing one (it's weird). But that does not change whether an incomplete type can be used as a parameter.

These two member functions, why don't they overload? [duplicate]

I would like to print two different things depending on whether a function is called statically with Foo::print() or from an instance of Foo foo; foo.print();
EDIT: Here is a class definition that definitely does not work, as answered by a few people already.
class Foo {
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
However, is there a good way of achieving this effect? Basically, I would like to do:
if(this is a static call)
do one thing
else
do another thing
Phrased in another way, I know PHP can check if the *this variable is defined or not to determine whether the function is called statically. Does C++ have the same capability?
No, it is directly prohibited by the standard:
ISO 14882:2003 C++ Standard 13.1/2 – Overloadable declarations
Certain function declarations cannot
be overloaded:
Function declarations that differ only in the return type cannot be overloaded.
Member function declarations with the same name and the same parameter types cannot be overloaded
if any of them is a static member function declaration (9.4).
...
[Example:
class X {
static void f();
void f(); // ill-formed
void f() const; // ill-formed
void f() const volatile; // ill-formed
void g();
void g() const; // OK: no static g
void g() const volatile; // OK: no static g
};
—end example]
...
Besides, it would be ambiguous anyway since it's possible to call static functions on instances:
ISO 14882:2003 C++ Standard 9.4/2 – Static members
A static member s of class X may be
referred to using the qualified-id
expression X::s; it is not necessary
to use the class member access syntax
(5.2.5) to refer to a static member. A
static member may be referred to using
the class member access syntax, in
which case the object-expression is
evaluated. [Example:
class process {
public:
static void reschedule();
}
process& g();
void f()
{
process::reschedule(); // OK: no object necessary
g().reschedule(); // g() is called
}
—end example]
...
So there would be ambiguity with what you have:
class Foo
{
public:
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
int main()
{
Foo f;
// Call the static or non-static member function?
// C++ standard 9.4/2 says that static member
// functions are callable via this syntax. But
// since there's also a non-static function named
// "print()", it is ambiguous.
f.print();
}
To address your question about whether you can check what instance a member function is being called on, there is the this keyword. The this keyword points to the object for which function was invoked. However, the this keyword will always point to an object i.e. it will never be NULL. Therefore it's not possible to check if a function is being called statically or not à la PHP.
ISO 14882:2003 C++ Standard 9.3.2/1 – The this pointer
In the body of a nonstatic (9.3)
member function, the keyword this is a
non-lvalue expression whose value is
the address of the object for which
the function is called.
It is definitely not allowed. I don't see any clean way of achieving this. What is exactly the problem that you want to solve this way?
You can't do that exactly, see In silico's answer.
But you can make Foo::print() and Foo foo; print(foo); do different things. (Define void print(Foo& foo) in the same namespace as class Foo, it will be found by ADL).
In any case, this is not a good idea. You have two functions very similar in name which do completely different things, which violates good design principles.
The answer is no, because you can't overload based on a return type.
You can certainly have static methods in a class, but you can't have:
static void foo();
void foo();
Because they have the same method signature.
EDIT: I saw your comment saying why you wanted to do this, and that you wanted to access member variables. You'd need to do this:
static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
int a = f.a;
// do something with a
}
(Or create getters and setters in Foo, etc, but that's the general idea)
1) In case of different return type of functions overloading is not possible in method overloading.
2) also if we pass same parameters in the functions define under the same class then it can not be overload.

Using (::) in a class's member function definition

I was testing out classes and I made this class
class Point
{
private:
int x,y;
public:
void setit(int new_x,int new_y);
void set_x(int new_x);
void set_y(int new_y);
int get_x();
int get_y();
};
now I went ahead and wrote the function definitions for all the public functions but,
There is something that puzzled me when i was writing the void set(int new_x,int new_y);
function definition
void Point::setit(int new_x, int new_y){
Point::set_x(new_x);
Point::set_y(new_y);
}
void Point::setit(int new_x, int new_y){
set_x(new_x);
set_y(new_y);
}
I noticed that the two previous function definitions have the exact same effect.
I thought that without the :: operator it wouldn't work because it would search for the functions outside the class, since I no longer signify they are in the Point class
Can anyone explain why they both have the same effect??
Thank You.
:: is the scope resolution operator; it can tell the compiler exactly where to look for a name.
The Point::set_x is simply an extended syntax for calling a member function.
set_x(new_x);
Is short for
this->set_x(new_x);
And
Point::set_x(new_x);
Is equivalent for
this->Point::set_x(new_x);
It allows you to select which function to call when a class hides a function in a parent class. For instance:
struct A {
void f();
};
struct B : public A {
void f(); // Hides A::f
};
B binst;
binst.f(); // Calls B::f
binst.A::f(); // Calls A::f
One thing you can do with this syntax is call the member function of a parent class from the overridden virtual function of a base class, allowing you to use the "default implementation" provided by the base class. You can also do it from outside the class, similar to hidden functions:
struct A {
virtual void f() {
cout << "A::f" << endl;
}
};
struct B : public A {
virtual void f() override {
cout << "B::f" << endl;
A::f(); // if we just did f(), it would call B::f, and we
// would get infinite recursion
}
};
B b;
b.f(); // prints B::f A::f
b.A::f(); // prints B::f
Inside a class member function, all the class member names are in scope, so set_x is found.
Moreover, the class name itself is visible inside class member functions (it is said to be injected), and thus Point::set_x is also found. But for the same reason, Point::Point::set_x and Point::Point::Point::Point::set_x are also ways to name the function.
:: is a scope resolution operator. To access the function in the scope of the Point class' namespace you can use the :: operator, but because the function setit(int new_x, int new_y) is already in the same scope as set_x and set_y, there is no requirement to define the overall scope of those functions. The program will call the functions with matching symbols to set_x and set_y in the most local scope.

C++ Overload Static Function with Non-Static Function

I would like to print two different things depending on whether a function is called statically with Foo::print() or from an instance of Foo foo; foo.print();
EDIT: Here is a class definition that definitely does not work, as answered by a few people already.
class Foo {
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
However, is there a good way of achieving this effect? Basically, I would like to do:
if(this is a static call)
do one thing
else
do another thing
Phrased in another way, I know PHP can check if the *this variable is defined or not to determine whether the function is called statically. Does C++ have the same capability?
No, it is directly prohibited by the standard:
ISO 14882:2003 C++ Standard 13.1/2 – Overloadable declarations
Certain function declarations cannot
be overloaded:
Function declarations that differ only in the return type cannot be overloaded.
Member function declarations with the same name and the same parameter types cannot be overloaded
if any of them is a static member function declaration (9.4).
...
[Example:
class X {
static void f();
void f(); // ill-formed
void f() const; // ill-formed
void f() const volatile; // ill-formed
void g();
void g() const; // OK: no static g
void g() const volatile; // OK: no static g
};
—end example]
...
Besides, it would be ambiguous anyway since it's possible to call static functions on instances:
ISO 14882:2003 C++ Standard 9.4/2 – Static members
A static member s of class X may be
referred to using the qualified-id
expression X::s; it is not necessary
to use the class member access syntax
(5.2.5) to refer to a static member. A
static member may be referred to using
the class member access syntax, in
which case the object-expression is
evaluated. [Example:
class process {
public:
static void reschedule();
}
process& g();
void f()
{
process::reschedule(); // OK: no object necessary
g().reschedule(); // g() is called
}
—end example]
...
So there would be ambiguity with what you have:
class Foo
{
public:
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
int main()
{
Foo f;
// Call the static or non-static member function?
// C++ standard 9.4/2 says that static member
// functions are callable via this syntax. But
// since there's also a non-static function named
// "print()", it is ambiguous.
f.print();
}
To address your question about whether you can check what instance a member function is being called on, there is the this keyword. The this keyword points to the object for which function was invoked. However, the this keyword will always point to an object i.e. it will never be NULL. Therefore it's not possible to check if a function is being called statically or not à la PHP.
ISO 14882:2003 C++ Standard 9.3.2/1 – The this pointer
In the body of a nonstatic (9.3)
member function, the keyword this is a
non-lvalue expression whose value is
the address of the object for which
the function is called.
It is definitely not allowed. I don't see any clean way of achieving this. What is exactly the problem that you want to solve this way?
You can't do that exactly, see In silico's answer.
But you can make Foo::print() and Foo foo; print(foo); do different things. (Define void print(Foo& foo) in the same namespace as class Foo, it will be found by ADL).
In any case, this is not a good idea. You have two functions very similar in name which do completely different things, which violates good design principles.
The answer is no, because you can't overload based on a return type.
You can certainly have static methods in a class, but you can't have:
static void foo();
void foo();
Because they have the same method signature.
EDIT: I saw your comment saying why you wanted to do this, and that you wanted to access member variables. You'd need to do this:
static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
int a = f.a;
// do something with a
}
(Or create getters and setters in Foo, etc, but that's the general idea)
1) In case of different return type of functions overloading is not possible in method overloading.
2) also if we pass same parameters in the functions define under the same class then it can not be overload.

C++ overload resolution [duplicate]

This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
Closed 8 years ago.
Given the following example, why do I have to explicitly use the statement b->A::DoSomething() rather than just b->DoSomething()?
Shouldn't the compiler's overload resolution figure out which method I'm talking about?
I'm using Microsoft VS 2005. (Note: using virtual doesn't help in this case.)
class A
{
public:
int DoSomething() {return 0;};
};
class B : public A
{
public:
int DoSomething(int x) {return 1;};
};
int main()
{
B* b = new B();
b->A::DoSomething(); //Why this?
//b->DoSomething(); //Why not this? (Gives compiler error.)
delete b;
return 0;
}
The two “overloads” aren't in the same scope. By default, the compiler only considers the smallest possible name scope until it finds a name match. Argument matching is done afterwards. In your case this means that the compiler sees B::DoSomething. It then tries to match the argument list, which fails.
One solution would be to pull down the overload from A into B's scope:
class B : public A {
public:
using A::DoSomething;
// …
}
Overload resolution is one of the ugliest parts of C++
Basically the compiler finds a name match "DoSomething(int)" in the scope of B, sees the parameters don't match, and stops with an error.
It can be overcome by using the A::DoSomething in class B
class A
{
public:
int DoSomething() {return 0;}
};
class B : public A
{
public:
using A::DoSomething;
int DoSomething(int x) {return 1;}
};
int main(int argc, char** argv)
{
B* b = new B();
// b->A::DoSomething(); // still works, but...
b->DoSomething(); // works now too
delete b;
return 0;
}
No, this behaviour is present to ensure that you don't get caught out inheriting from distant base classes by mistake.
To get around it, you need to tell the compiler which method you want to call by placing a using A::DoSomething in the B class.
See this article for a quick and easy overview of this behaviour.
The presence of a method in a derived class hides all methods with the same name (regardless of parameters) in base classes. This is done to avoid problems like this:
class A {} ;
class B :public A
{
void DoSomething(long) {...}
}
B b;
b.DoSomething(1); // calls B::DoSomething((long)1));
than later someone changes class A:
class A
{
void DoSomething(int ) {...}
}
now suddenly:
B b;
b.DoSomething(1); // calls A::DoSomething(1);
In other words, if it didn't work like this, a unrelated change in a class you don't control (A), could silently affect how your code works.
This has something to do with the way name resolution works. Basically, we first find the scope from which the name comes, and then we collect all overloads for that name in that scope. However, the scope in your case is class B, and in class B, B::DoSomething hides A::DOSomething:
3.3.7 Name hiding [basic.scope.hiding]
...[snip]...
3 In a member function definition, the declaration of a local name hides
the declaration of a member of the class with the same name; see
basic.scope.class. The declaration of a member in a derived class
(class.derived) hides the declaration of a member of a base class of
the same name; see class.member.lookup.
Because of name hiding, A::DoSomething is not even considered for overload resolution
When you define a function in a derived class then it hides all the functions with that name in the base class. If the base class function is virtual and has a compatible signature then the derived class function also overrides the base class function. However, that doesn't affect the visibility.
You can make the base class function visible with a using declaration:
class B : public A
{
public:
int DoSomething(int x) {return 1;};
using A::DoSomething;
};
That's not overloading! That's HIDING!
When searching up the inheritance tree for the function to use, C++ uses the name without arguments, once it has found any definition it stops, then examines the arguments. In the example given, it stops in class B. In order to be able to do what you are after, class B should be defined like this:
class B : public A
{
public:
using A::DoSomething;
int DoSomething(int x) {return 1;};
};
The function is hidden by the function with the same name in the subclass (but with a different signature). You can unhide it by using the using statement, as in using A::DoSomething();