2

I am implementing a class using singleton for logging purposes.

Log *Log::getInstance(){

    if(!Log::log) Log::log = new Log::Log();
    
    return Log::log;
}

Here, Log::log is a pointer to an object of Log class. This snnipet of code generates the error "expected type-specifier" on new Log::Log(), but if I ommit the scope resolution operator, it works fine. Why?

1 Answers1

5

Log is the class type.

Log::Log is a syntax construct that in certain contexts refers to Log's constructor. However it doesn't generally name it as in the names of other functions (e.g. for the purpose of address-taking).

new expects a type name. That is simply the syntax. Log(...) in a new-expression like new Log(...) will call the constructor according to the arguments ... implicitly to construct the new object, even though Log is its type name, not referring to its constructor. This is consistent with the syntax for non-class types, such as new int(1).

Therefore, remove ::Log from Log::Log.


Constructors are never called explicitly in C++. You only have syntax of the form type(...) or type{...} which implicitly call constructors for class types to construct new objects. The only case where it might make sense to informally talk about "calling" a constructor might be deferred construction, in which one constructor "calls" another constructor in its member-initializer-list.


I should add that you should not implement a singleton this way. You have no way of destroying the object you created in the new expression automatically at program end and the initialization is not thread-safe. See e.g. this question and others for C++ singleton designs.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • So I only have to call the constructor if I'm passing arguments to it? – Cícero Augusto Jan 08 '22 at 03:02
  • 1
    @CíceroAugusto You never call a constructor explicitly in C++ (except in the member-initializer-list of another constructor for deferred construction). – user17732522 Jan 08 '22 at 03:04
  • 1
    The current standard says that the constructor does not get a name (not even the name of the class) and that being called as Log::Log is just syntax. You can also not take the address of the constructor. – Sebastian Jan 08 '22 at 04:39
  • 1
    @Sebastian I have updated the answer to reflect that. – user17732522 Jan 08 '22 at 04:49