简体   繁体   中英

Where to put non-member function definition of a PRIVATE nested (inner)class?

Following is a simple example of my actual problem. I have a non-member function defined using friend keyword in the InnerClass . The definition of this function should be outside of InnerClass .

On the other hand, the class definition is under private of MyClass as I want to use the InnerClass specifically for MyClass .

In this case, where I can actually put the definition of friend function?

#include <iostream>

class MyClass
{
private:
    class InnerClass
    {
        int m_int;
    public:
        InnerClass(int i) :m_int(i) {}

        // non-member (friend) function, for which I need a definition outside the class!
        friend std::ostream& operator<<(std::ostream& output, const InnerClass &obj);
    };
    // ERROR: too many parameter for this operator
    std::ostream& operator<<(std::ostream& output, const InnerClass &obj)
    {
        return output << obj.m_int << " ";
    }

private:
    InnerClass m_innerClass;

public:
    explicit MyClass(int i) : m_innerClass{ i } {}
    friend std::ostream& operator<<(std::ostream& output, const MyClass &obj);
};

std::ostream& operator<<(std::ostream& output, const MyClass &obj)
{
    output << obj.m_innerClass << std::endl;
}


int main()
{
    MyClass classObj{ 2 };
    std::cout << classObj;
    return 0;
}

The error msg:

  \main.cpp(27): error C2804: binary 'operator <<' has too many parameters
  \main.cpp(27): error C2333: 'MyClass::operator <<': error in function declaration; skipping function body

You can actualy define friend non-member functions right inside the class definition.

Here's your code snippet fixed:

#include <iostream>

class MyClass
{
private:
    class InnerClass
    {
        int m_int;
    public:
        InnerClass(int i) :m_int(i) {}

        // non-member (friend) function, which we can define right here
        friend std::ostream& operator<<(std::ostream& output, const InnerClass &obj)
        {
            return output << obj.m_int << " ";
        }
    };    

private:
    InnerClass m_innerClass;

public:
    explicit MyClass(int i) : m_innerClass{ i } {}
    friend std::ostream& operator<<(std::ostream& output, const MyClass &obj);
};

std::ostream& operator<<(std::ostream& output, const MyClass &obj)
{
   return output << obj.m_innerClass << std::endl;
}


int main()
{
    MyClass classObj{ 2 };
    std::cout << classObj;
    return 0;
}

You could do the same with the other operator<< .

Now, if InnerClass weren't private, you could still define the function at the global scope, but you'd need to fully qualify second parameter's name:

std::ostream& operator<<(std::ostream& output, const MyClass::InnerClass &obj)
{                                                //  ^^^^^^^^^^^^^^^^^^^ 
    return output << obj.m_int << " ";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM