注册 登录
编程论坛 C++教室

关于运算符重载中的string类型问题

linw1225 发布于 2011-05-19 17:51, 2485 次点击
请看看以下代码:
程序代码:
#include<iostream.h>
#include<string.h>
class String
{
    public:
        String(string);
        
        ~String();

        void Show();
        friend bool operator == (const String &s1,const String &s2);
        friend String operator >(const String &s1,const String &s2);
    private:
        string  str;
};

String::String(int s)
{
    str=s;
}
String::~String()
{}

void String::Show()
{
    cout<<str<<endl;
}

bool operator == (const String &s1,const String &s2)
{
    return (s1.str==s2.str);
}

String operator >(const String &s1,const String &s2)
{
    if(s1.str>s2.str)
        return s1;
    else
        return s2;
}

int main()
{
    string a,b;
    cin>>a;
    cin>>b;

    String s1(a),s2(b),s3;

    if(s1==s2)
        cout<<"相等"<<endl;
    else
        cout<<""<<endl;


    s3=(s1>s2);
    s3.Show();

    return 0;
}

   

这段代码是错误的。
会产生如下错误:
2011051901.cpp(36) : error C2248: 'str' : cannot access private member declared in class 'String'
当然,错误不只这一个,其他的错误跟这个一样。
问了老师,她说私有数据里面不能有string类型
然后我改了下代码把string类型换成int的话就正确。
就是想问:
1、运算符重载里面string类型为什么不能使用?
2、不使用运算符重载,一般的类里面是不是就可以用到string类型?
3、接上一问,如果string类型不能用,那么我想表示一个不限长度的字符串是不是只能用char *str;?
4、假如私有数据类型里面的那个是int类型,头文件定义要定义成#include<iostream.h>
   是不是所有关于运算符重载的头文件定义都必须是:#include<iostream.h>
   而不能是#include<iostream>
           using namespace std;
11 回复
#2
linw12252011-05-19 17:53
忘了说了,这个代码要实现的目的是:
定义一个字符串类String,用来存放不定长的字符串,重载运算符“= =”、“<”和“>”,用于两个字符串的等于、小于和大于的比较运算。
这个代码处于调试阶段,所以重载运算符“<”的函数没写。
然后主函数里面也是粗略的写下,请见谅。
#3
debroa7232011-05-19 23:48
1、不是string 类型不能使用,而是不能访问类的私有成员(那段E文错误提示已经很清晰地回答 了这个问题)
增加一个公有函数来访问这个私有的 string
const string& Get(void)const{return str;}

使用: (s1.Get()==s2.Get());

2 3、类成员当然可以有string类型,也当然可以是私有的,只是访问有限制。
4、使用预编译,可以避免在每个头文件中包含
#include<iostream>
using namespace std;
#4
linw12252011-05-20 20:21
回复 3楼 debroa723
如果把string类型改成int类型的话,程序就可以运行,就不会出现所说的错误。
那么是不是,对私有的访问限制只是因为它是string类型?
string类型的私有数据需要另外定义函数才能访问?


呃,然后……预编译是啥?
避免出现 #include <iostream>
         using namespace std;
是不是就是说在运算符重载中不能以该形式,而应该是 #include <iostream.h>?
#5
laigaoat20052011-05-20 22:28
程序代码:
//改过了,能运行了。不知道达到你要求没有。没有时间,你自己看看吧。

#include<iostream.h>
#include<string>
using namespace std;

class String
{
    public:
        String(string);
        String();     
        ~String();
        void Show();
        friend bool operator == (const String &s1,const String &s2);
        friend String operator >(const String &s1,const String &s2);
    private:
        string  str;
};
String::String()
{
   
}
String::String(string s)
{
    str=s;
}
String::~String()
{}

void String::Show()
{
    cout << str << endl;
}

bool operator == (const String &s1,const String &s2)
{
    return (s1.str==s2.str);
}

String operator >(const String &s1,const String &s2)
{
    if(s1.str>s2.str)
        return s1;
    else
        return s2;
}

int main()
{
    string a,b;
    cin>>a;
    cin>>b;

    String s1(a);
    String s2(b);
    String s3;

    if(s1==s2)
        cout<<"相等"<<endl;
    else
        cout<<""<<endl;


    s3=(s1>s2);
    s3.Show();

    return 0;
}

#6
linw12252011-05-20 22:54
回复 5楼 laigaoat2005
能运行么?
不行啊。
还是有出现相同的错误,就是上面提到的那个问题。
#7
ishagua2011-05-21 02:11
看这个代码  或许对你有帮助

https://bbs.bccn.net/thread-340594-1-1.html
#8
laigaoat20052011-05-21 10:33
不知道lz用什么编译的?
#9
linw12252011-05-21 20:12
回复 8楼 laigaoat2005
VC6.0
#10
linw12252011-05-21 21:09
回复 3楼 debroa723
去调试了下,不行。
#11
debroa7232011-05-22 22:00
你的代码,我在VS2010下,以下几个地方的改动后,编译通过。
1 包含的头文件改为
#include <iostream>
#include <string>
2构造器 
String::String(int s)
{
    str=s;
}
改为
String(const string& s);
String::String(const string& s):str(s)
{
}
3 增加默认构造器
String(void):str("")
{
}
我不知道VC6下为何报出不能访问私有成员的错误而到了VS2010下就没有报了,手上也没有VC6,所以也无从研究。猜想可能是头文件的差别吧。

至于预编译,打开工程属性中的使用预编译头的属性,一般在VS生成项目时,都会自动生成文件stdafx.h stdafx.cpp,它们就是预编译头,你将工程中其它地方的#include全都放到这里,其它地方的就全部去掉,然后在所有CPP文件中增加#include "stdafx.h",每当增加头文件时,都只是加入到stdafx.h中。而stdafx.h中的包含顺序也是需要认真考虑的,合理的程序代码和结构才能做到这一点(所有包含全在头文件中)。
#12
linw12252011-05-24 14:02
回复 11楼 debroa723
果然VC6.0是不行的。
好吧,我们才刚学,貌似这样的类型都是定义一个非常长的字符数组实现输入。
大概以后就能知道了。
麻烦了。
1