这是我的任务:
写出具有以下内容的Word:
这是我的解决方案。我没有错误地编译它,但它没有像它那样工作。
#include <iostream>
#include <string.h>
using namespace std;
class Word
{
private:
char *content;
int length;
public:
Word();
Word(char *);
~Word();
void print_content(void);
int check_character(char);
friend int check_number(Word,Word);
};
Word::Word()
{
}
Word::Word(char *n)
{
length=strlen(n);
content=new char [length];
for(int i=0;i<length;i++)
{
content[i]=n[i];
}
}
Word::~Word()
{
delete content;
}
void Word::print_content(void)
{
for(int i=0;i<length;i++)
{
cout<<""<<content[i];
}
}
int Word::check_character(char a)
{
int position=0;
for(int i=0;i<length;i++)
{
if(content[i]==a)
{
position=i+1;
}
}
if(position>0)
{
return position;
}
else return 0;
}
int check_number(Word n,Word m)
{
int counter_n=0;
int counter_m=0;
for(int i=1;i<n.length;i++)
{
if((n.content[i-1]=='1')&&(n.content[i]=='0'))
{
counter_n=counter_n+1;
}
}
for(int i=1;i<m.length;i++)
{
if((m.content[i-1]=='1')&&(m.content[i]=='0'))
{
counter_m=counter_m+1;
}
}
if(counter_n>counter_m)
{
return counter_n;
}
else if(counter_n<counter_m)
{
return counter_m;
}
else return 0;
}
int main()
{
char characters1[]="qwerty10",*p1,*p2;
char characters2[]="stackoverflow101010";
p1=characters1;
p2=characters2;
Word first(p1);
Word second(p2);
cout<<""<<first.check_character('q')<<endl;
cout<<""<<second.check_character('f')<<endl;
//cout<<""<<check_number(first,second)<<endl;
first.print_content();
second.print_content();
}
函数check_number(第一个,第二个)由于某种原因使其他函数无法正常工作,如果你通过删除&#34; //&#34;你会看到first.print_content()和second.print_content()没有给我们正确的结果。或者,如果首先调用函数first.check_character(&#39; r&#39;),则调用second.check_character(&#39; j&#39;),然后调用check_number(第一个,第二个),然后调用两个第一个函数don& #39;工作。 这种奇怪行为的原因是什么?
答案 0 :(得分:2)
Word
个对象通过副本传递给check_number
,但您没有定义复制构造函数。因此编译器使用默认值,并且这一个复制指针(char* content
)。传递给函数的临时对象指向主函数中创建的first
和second
的数据...删除后(调用函数后删除temprary对象),它们删除指针,因此{ {1}}和first
个对象指向已删除的内存。你在这里有不确定的行为,这解释了你经历的副作用。
通过引用second
传递对象是解决问题的简便方法。这是一个工作代码(包括许多修复,因为您没有正确访问数组):
check_number
输出:
#include <iostream>
using namespace std;
#include <iostream>
#include <string.h>
using namespace std;
class Word
{
private:
char *content;
int length;
public:
Word();
Word(char *);
~Word();
void print_content(void);
int check_character(char);
friend int check_number(const Word&,const Word&); // changed here
};
Word::Word()
{
}
Word::Word(char *n)
{
length=strlen(n);
content=new char [length];
for(int i=0;i<length;i++)
{
content[i]=n[i]; // changed here
}
}
Word::~Word()
{
delete [] content; // changed here
}
void Word::print_content(void)
{
for(int i=0;i<length;i++)
{
cout<<""<<content[i]; // changed here
}
}
int Word::check_character(char a)
{
int position=0;
for(int i=0;i<length;i++)
{
if(content[i]==a) // changed here
{
position=i+1;
}
}
if(position>0)
{
return position;
}
else return 0;
}
int check_number( const Word& n, const Word& m)// changed here
{
int counter_n=0;
int counter_m=0;
for(int i=1;i<n.length;i++)
{
if((n.content[i-1]=='1')&&(n.content[i]=='0')) // changed here
{
counter_n=counter_n+1;
}
}
for(int i=1;i<m.length;i++)
{
if((m.content[i-1]=='1')&&(m.content[i]=='0')) // changed here
{
counter_m=counter_m+1;
}
}
if(counter_n>counter_m)
{
return counter_n;
}
else if(counter_n<counter_m)
{
return counter_m;
}
else return 0;
}
int main()
{
char characters1[]="qwerty10",*p1,*p2;
char characters2[]="stackoverflow101010";
p1=characters1;
p2=characters2;
Word first(p1);
Word second(p2);
cout<<""<<first.check_character('q')<<endl;
cout<<""<<second.check_character('f')<<endl;
cout<<""<<check_number(first,second)<<endl;
first.print_content();
second.print_content();
}
声明复制构造函数是另一种解决问题的方法:
1
10
3
qwerty10stackoverflow101010
这比通过const引用传递对象效率低,但会使代码更安全(总是声明复制构造函数以防止你在这里遇到的bug)。
最后,如果你是懒惰的,你也可以将复制构造函数声明为私有,以防止编译器复制对象,只是声明它,不要强迫它:
Word( const Wodr& word ) :
length( word.length ),
content( new char[word.length] )
{
memcpy( content, word.content, word.length );
}
然后,编译器不会让你调用check_number。