3

I want to create functions with dot operator like these:

Regedit.Key.Create();
Regedit.Value.Create();
Regedit.Value.Read();

How can I do that?

  • You cannot overload dot operator in C++. – user17537755 Dec 02 '21 at 07:24
  • @user17537755 Can I overload arrow or colon operator in C++? –  Dec 02 '21 at 07:26
  • What is `Regedit` supposed to be? What is `Regedit.Key` and `Regedit.Value` supposed to be? If e.g. `Regedit.Key` is supposed to be a function that returns and object, you must *call* it. – Some programmer dude Dec 02 '21 at 07:28
  • 2
    To fellow reviewers, I don't see the need for closing this question. It is a valid question for someone new to C++ – Pepijn Kramer Dec 02 '21 at 07:30
  • I vote to reopen. While it is probably not possible to do the semantic of what OP wants, I feel that there can be reasonable "As close as possible" answers for the desired syntax. And my gut feeling says that on this angle it is possible to get even closer than Pepijns answer. – Yunnosch Dec 02 '21 at 07:41
  • It is possible provided 1/ `Regedit` is an instance of a class having `Key` and `Value` attributes 2/ Those attributes are instances of classes having `Read` and `Create` methods. – Serge Ballesta Dec 02 '21 at 07:41
  • @ÇAĞATAY KAYA Here: https://learn.microsoft.com/en-us/cpp/cpp/operator-overloading?view=msvc-170 , this is a list of operators you can overload. But I think you need to clarify what is a nested function. – user17537755 Dec 02 '21 at 08:29
  • @SergeBallesta That would require public data members which is generally not that good for maintainability. https://stackoverflow.com/questions/2977007/public-data-members-vs-getters-setters – Pepijn Kramer Dec 02 '21 at 09:23
  • 1
    @PepijnKramer C++ is not Java. There is nothing wrong for a member attribute to be part of the public interface, provided the accesses are trivial. As far as I am concerned, I only use getters/setters for read only attributes, of is the getter or setter is not trivial (auxilliary operations required for example a synchronization...). – Serge Ballesta Dec 02 '21 at 09:35

2 Answers2

3

In C++ you will need to write getter functions, and then the syntax becomes editor.Key().Create();

class Key
{
public:
    Key() = default;
    ~Key() = default;

    void Create() 
    {
    };
};

class RegEdit
{
public:
    // in C++ you need to use a getter function 
    Key& key() 
    {
        return m_key;
    }

private:
    Key m_key;
};

int main()
{
    RegEdit editor;
    editor.key().Create();

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • That won't compile. `Key& Key()` should not be const (or should return `const Key&`. Besides, your code has naming collisions. Last but not least, you forgot to mention structs, in that case getters won't be needed. – alagner Dec 02 '21 at 09:39
  • Good points, and structs might work too. I still prefer classes with getters and setters. Over the years I've found that they are more maintainable (refactoring internals of the class while keeping the "interface" the same.), and you can add logic to setter to check input. – Pepijn Kramer Dec 02 '21 at 10:21
1

For Regedit.Key.Create(); to be a valid C++ instruction, some conditions are required:

  • Regedit must be an object (ie an instance of a C++ class)
  • Key must be a member attribute of Regedit
  • that attribute must also be an object
  • Create must be a method of that object

Here is an example code meeting those conditions, where RegAccessor is the class for Regedit and Selector is the class for Regedit.Key:

#include <iostream>

class Selector {
public:
    enum class Type {
        Key,
        Value
    };
    friend std::ostream& operator << (std::ostream& out, const Type& type) {
        const char *name;
        switch (type) {
            case Type::Key: name = "Key"; break;
            case Type::Value: name="Value"; break;
            default: name="Unknown";
        }
        out << name;
        return out;
    }
    
    Selector(Type type): type(type) {};
    
    void Create() {
        // write more relevant code here...
        std::cout << "Create " << type << " called\n";
    }
    void Read() {
         // write more relevant code here...
       std::cout << "Read " << type << " called\n";
    }

private:
    Type type;
};



class RegAccessor {
public:
    Selector Key = Selector::Type::Key;
    Selector Value = Selector::Type::Value;
};

int main(int argc, char **argv)
{
    RegAccessor Regedit;
    // here is exactly your example code
    Regedit.Key.Create();
    Regedit.Value.Create();
    Regedit.Value.Read();
    return 0;
}
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252