C ++ - 一个功能使其他人出现故障

时间:2015-03-21 12:45:35

标签: c++

这是我的任务:

写出具有以下内容的Word:

  1. 指向字符数组
  2. 构造函数和析构函数
  3. 阅读单词的功能
  4. 用于检查作为参数传递给它的字符是否出现在单词和出现的返回位置
  5. 用于检查两个单词中哪一个更多出现10号并返回该出现次数
  6. 这是我的解决方案。我没有错误地编译它,但它没有像它那样工作。

    #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;工作。 这种奇怪行为的原因是什么?

1 个答案:

答案 0 :(得分:2)

Word个对象通过副本传递给check_number,但您没有定义复制构造函数。因此编译器使用默认值,并且这一个复制指针(char* content)。传递给函数的临时对象指向主函数中创建的firstsecond的数据...删除后(调用函数后删除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。