Z
Z
zus2015-10-09 22:18:35
Programming
zus, 2015-10-09 22:18:35

ClassName::functionName or objectName.functionName?

Hi all!
I am learning C++ and I have a question.
Why do we sometimes use a construct like ClassName::functionName and sometimes objectName.functionName ? Those. for example, in the file with main we specify the second option, and in the file with the function logic we use the first option? What does it depend on.
I understand that cout << objectName.functionName means that we output the return data of a function that belongs to a class object (operates with object data).
But that's why we sometimes use cout << ClassName::functionName instead of the first option, I can't figure it out...
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Stanislav Makarov, 2015-10-10
@Nipheris

I will answer without guesswork.
> I understand that cout << objectName.functionName means that we output the return data of a function that belongs to a class object (operates with object data).
This is well consistent with the truth, in general, there is nothing to add.
> But that's why we sometimes use cout << ClassName::functionName instead of the first option, I can't figure it out...
"::" is the scope extension operator. In C++, different entities can be declared "inside" other entities. For example, functions inside classes, as in your case - then they become methods. Classes, functions and variables can be declared inside namespaces. Classes can be declared within other classes. Classes can even be declared within function definitions.
In all these and other cases, we can talk about two entity names - a short one, which is unique within the parent entity, and a full one, by which the entity can be accessed from anywhere in the program. For example,

namespace MyLibrary {
    namespace UI {
        class Widget {
         ///
        };
        class Controller {
        private:
            Widget *widget; // Здесь Widget будет видно по короткому имени
        };
    }
}

namespace App {
  MyLibrary::UI::Widget *w; // А вот здесь уже нужно использовать полное
}

This rule applies to everything - classes, functions, and variables. And just to build the full name, the operator "::" is needed. Roughly speaking, it "opens" the entity you specify, and after it you can specify the name of the nested entity. MyLibrary::UI::Widget - opened the MyLibrary namespace, took and opened the UI namespace in it, took the Widget entity in it. In our case, Widget is a class, so we can use it as a type, such as declaring a pointer to its object. If we had a mainWidget variable in the same UI, we could write this:
Here's the deal with the dot. By default, functions inside classes are considered methods of an OBJECT (an instance of this class), and, as you rightly said, operate on the object's data, which means they CANNOT be called without specifying that object. In other words, they are not independent; to call them, you always need to specify the object with which the method will work. You can imagine that all instance methods have an implicit this parameter, which, although not written in the list, is nevertheless always present, and its value must be set. The dot operator is the way to set the value of "this" - i.e. specify on which object the method is called.
Quite another matter - static-methods. In fact, these are independent functions, they are simply declared inside the class, and have access to its private entities. Therefore, to call them, it is enough to specify the full name using the "::" operator, for example, Widget::create or MyLibrary::UI:Widget::create, which are basically the same thing. A more complete notation is needed when you're in a different scope and just "don't see" the ID you want. Or if you have MULTIPLE identifiers with the same name in the current scope (name conflict), and the compiler needs to unambiguously understand which entity you are talking about.
Regarding the case that you do not understand - about using :: in a compound method name - everything is simple here. Because you're not going to CALL the method, but DEFINING it, you don't need a dot, because dot is the syntax for invoking a method on a particular object. You just need to construct the FULL name for the method inside the class so that the compiler understands WHOSE code you will write in curly braces. And the full name is built using a colon, which is why we get ClassName::methodName { method code }. You cannot simply write methodName, because in the cpp file, you are NO LONGER INSIDE the CLASS definition, and the compiler will consider that you are declaring and describing a completely different, free function methodName, which has absolutely nothing to do with the methodName method in the ClassName class.
"::" has some interesting features, such as when there is nothing to the left of it. This means that you are accessing the global scope. This allows you, for example, to distinguish between a global function and a function of the same name defined in your scope. This can be read in a decent book.
If you have any questions - ask. The easiest way to remember is this: a dot is a call to a member of a structure object or a method call (that is, an object is always to the left of the dot), and "::" is a way to compose the NAME of any element of your program - a class, function, method, variable, etc.

T
Tlito, 2015-10-09
@tlito

through a dot is a call to the function of the object.
and through a double colon - this is an indication of the scope seems.
for example
, here is an indication of the scope of the function, well, or the class std. probably it is 1 such object of class std.
but this is all guesswork.

A
AtomKrieg, 2015-10-10
@AtomKrieg

ClassName::functionName and sometimes objectName.functionName

Is this a question about static methods? Think of a static class method as a function in the namespace of the class name.
#include <iostream>
using namespace std;

class Test
{
public:
  static void st() { cout << "static" << endl; }
  void nonst() {cout << "non static" << endl; }
};

int main(int argc, char **argv)
{
  Test t;

  Test::st(); // для статик метода можно так
  t.st(); //и так тоже можно

  Test::nonst(); // compilation error: так нельзя для не статик метода
  t.nonst();  //можно только так

  system("pause");
  return 0;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question