您的位置:首页 > 编程语言 > C语言/C++

c++顺序编译问题

2012-09-25 21:20 316 查看
#include <iostream>
#include  <string.h>
#define NO_ASSIGN(T) T(const T& rhs); \
 T& operator= (const T& rhs);
 using namespace std;

class String {
    struct Srep;
    Srep *rep;
public:
    class Cref;

    class Range{};

    String();
    String(const char*);
    String(const String&);
    String& operator= (const String&);
    String& operator= (const char*);
    ~String();

    void check(int i) const {
        if (i<0 || rep->sz <= i) throw Range();  //虽然前置声明类,但编译器并不知道类里有sz这个成员,编译出错。
    }

    char read(int i) const { return rep->s[i]; }

    void write(int i, char c) {
        rep = rep->get_new_copy();
        rep->s[i] = c;
    }

    Cref operator[] (int i) {
        check(i); return Cref(*this, i);
    }
    char operator[] (int i) const {
        check(i);
        return rep->s[i];
    }

    int size() const { return rep->sz; }
};

struct String::Srep {
    Srep(int nsz, const char *p) {
        n = 1;
        sz = nsz;
        s = new char[sz+1];
        strcpy(s, p);
    }

    ~Srep() { delete []s;}

    Srep* get_new_copy() {
        if (n == 1) return this;
        n--;
        return new Srep(sz, s);
    }

    void assign(int nsz, const char *p) {
        if (sz != nsz) {
            delete []s;
            sz = nsz;
            s = new char[sz+1];
        }
        strcpy(s, p);
    }
    char *s;
    int sz;
    int n;

    NO_ASSIGN(Srep)
};

class String::Cref {
friend class String;
    String& s;
    int i;
    Cref(String& ss, int index) : s(ss), i(index) { }
public:
    void operator= (char ch) {
        s.write(i,ch);
    }
    operator char() const { return s.read(i);}

};

String::String() {
    rep = new Srep(0,"");
}

String::String(const String& rhs) {
    rhs.rep->n++;
    rep = rhs.rep;
}

String::String(const char* ch) {
    rep = new Srep(strlen(ch), ch);
}

String& String::operator=(const String& rhs) {
    if(this == &rhs) return *this;
    rhs.rep->n++;
    if(--rep->n == 0) delete rep;
    rep = rhs.rep;
    return *this;
}

String& String::operator=(const char* ch) {
    if (rep->n == 1)
        rep->assign(strlen(ch), ch);
    else {
        rep = new Srep(strlen(ch), ch);
    }
    return *this;
}


为了解决上述问题。不要把成员函数写成内联的。而是在Srep,Cref定义之后写。

#include <iostream>
#include  <string.h>
#define NO_ASSIGN(T) T(const T& rhs); \
  T& operator= (const T& rhs);

using namespace std;

class String {
  struct Srep;
  Srep *rep;
public:
  class Cref;

  class Range{};

  String();
  String(const char*);
  String(const String&);
  String& operator= (const String&);
  String& operator= (const char*);
  ~String();

  void check(int i) const;
  char read(int i) const;

  void write(int i, char c);
  Cref operator[] (int i);
  char operator[] (int i) const;
  int size() const;
};

class String::Cref {
  friend class String;
  String& s;
  int i;
  Cref(String& ss, int index) : s(ss), i(index) { }
public:
  void operator= (char ch) {
    s.write(i,ch);
  }
  operator char() const { return s.read(i);}

};

struct String::Srep {
  Srep(int nsz, const char *p) {
    n = 1;
    sz = nsz;
    s = new char[sz+1];
    strcpy(s, p);
  }

  ~Srep() { delete []s;}

  Srep* get_new_copy() {
    if (n == 1) return this;
    n--;
    return new Srep(sz, s);
  }

  void assign(int nsz, const char *p) {
    if (sz != nsz) {
      delete []s;
      sz = nsz;
      s = new char[sz+1];
    }
    strcpy(s, p);
  }
  char *s;
  int sz;
  int n;

  NO_ASSIGN(Srep)
};

String::String() {
  rep = new Srep(0,"");
}

String::String(const String& rhs) {
  rhs.rep->n++;
  rep = rhs.rep;
}

String::String(const char* ch) {
  rep = new Srep(strlen(ch), ch);
}

String& String::operator=(const String& rhs) {
  if(this == &rhs) return *this;
  rhs.rep->n++;
  if(--rep->n == 0) delete rep;
  rep = rhs.rep;
  return *this;
}

String& String::operator=(const char* ch) {
  if (rep->n == 1)
    rep->assign(strlen(ch), ch);
  else {
    rep = new Srep(strlen(ch), ch);
  }
  return *this;
}

void String::check(int i) const {
  if (i<0 || rep->sz <= i) throw Range();
}

char String::read(int i) const { return rep->s[i]; }

void String::write(int i, char c) {
  rep = rep->get_new_copy();
  rep->s[i] = c;
}

String::Cref String::operator[] (int i) {
  check(i);
  return Cref(*this, i);
}
char String::operator[] (int i) const {
  check(i);
  return rep->s[i];
}

int String::size() const { return rep->sz; }

int main() {
  return 0;
}


由此可见c++的编译器是顺序编译的。即使在同一个文件里,也要注意先后顺序的问题。

如果你定义struct Srep 也会报错。因为在String里声明Screp是嵌套类,在String的域名空间里。与全局控件是不同的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: