【问题标题】:C++ friend function can't access private membersC++友元函数不能访问私有成员
【发布时间】:2023-03-24 18:22:01
【问题描述】:

这应该是一个带有一堆运算符和函数的字符串类,包括两个友元函数。这两个给我带来了一些麻烦,因为编译器说他们不能访问私有成员。这是我的 string.h:

#include <iostream>
#ifndef STR_H
#define STR_H

namespace MyStr
{
class Str
{
private:
    unsigned int length;
    char *data;
public:
    Str();
    Str(const Str&);
    Str(const char*);
    Str(char c, unsigned int db);
    ~Str();
    char* cStr() const;
    unsigned int getLength() const;

这里有很多不相关的功能......

    friend int operator/ (const Str&, char);
    friend std::ostream& operator<< (std::ostream&, const Str&);
};
}
#endif /* STR_H */

这里是main.cpp:

#include <iostream>
#include "Str.h"

using namespace std;
using namespace MyStr;

ostream& operator<< (ostream& out,const Str& str)
{
    for (int i=0; i<str.length; i++)
    {
        out<<str.data[i];
    }
    out<<endl;
    return out;
}

int operator/ (const Str& str, char c)
{
    for (int i=0; i<str.length; i++)
    {
        if(str.data[i]==c) return i;
    }
    return -1;
}

此代码无法编译,编译器声称 Str 成员是私有的。

【问题讨论】:

  • 你遇到了什么错误?
  • 错误:'char* MyStr::Str::data' 是私有的|错误:'unsigned int MyStr::Str::length' 是私有的|
  • 它在哪一行发出该错误?两种功能都适用吗?
  • Str.h|10|错误:'unsigned int MyStr::Str::length' 是私有的|两种功能。当函数尝试访问私有成员时会发生这些错误,如下所示:
  • 你对友元函数的定义和声明在不同的命名空间中。

标签: c++ operator-overloading friend


【解决方案1】:

你应该多注意命名空间。

class Str {
private:
    unsigned int length;
    char *data;
public:
    Str(){}
    Str(const Str&){}
    Str(const char*){}
    Str(char c, unsigned int db){}
    // maybe something more...
    friend int operator/ (const Str&, char);
    friend std::ostream& operator<< (std::ostream&, const Str&);
};

ostream& operator<< (ostream& out,const Str& str)
{
    for (int i=0; i<str.length; i++)
        out<<str.data[i];
    out<<endl;
    return out;
}

int operator/ (const Str& str, char c)
{
    for (int i=0; i<str.length; i++)
        if(str.data[i]==c) return i;

    return -1;
}

int main()
{
    Str s;
    cout<<s;
    return 0;
}

由于名称空间不匹配,您会收到错误消息。如果您更喜欢使用MyStr,那么您应该将命名空间MyStr 添加到重载的friend 运算符。你可以这样做:(操作符应该在命名空间MyStr中定义)

namespace MyStr {  
    ostream& operator<< (ostream& out,const Str& str)
    {
        for (int i=0; i<str.length; i++)
        {
             out<<str.data[i];
         }
        out<<endl;
        return out;
    }

    int operator/ (const Str& str, char c)
    {
        for (int i=0; i<str.length; i++)
        {
            if(str.data[i]==c) return i;
        }
        return -1;
    }
}

【讨论】:

    【解决方案2】:

    当您在 Str 中声明友元函数时,它们被认为位于紧接的命名空间 MyStr 中。

    您定义的运算符位于全局命名空间中,因此编译器认为这是两个完全不同的运算符,而不是朋友。

    你可以通过添加来解决这个问题

    namespace MyStr
    {
    
    }
    

    围绕 .cpp 文件中的运算符。

    【讨论】:

    • 我正在尝试,但它不起作用 -- liveworkspace.org/code/4yc7Hy$3217
    • @David - 这是不同的。您尝试在 main 中访问 s.x,而 main 不是该类的朋友。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2014-08-21
    • 2021-08-16
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    相关资源
    最近更新 更多