zoukankan      html  css  js  c++  java
  • c++学习笔记(二)

    1. C++内存布局分为几个区域,各自具备什么特点?
    分为
    内核区: Kernel Space User code CANNOT read from nor write
    to these address, doing so result in a Segmentation Fault.
    堆区、
    栈区、
    数据段{

    【(全局静态区/全局变量---->bss segment)】
    Uninitialized static variables, filed with zero,

    【静态变量(data segment)】
    Static Variables initialized by the programmer.
    【只读段 /文字常量区 代码段区 text segemnt】
    Store the binary image of the process.
    }

    2. 当定义类时,编译器会为类自动生成哪些函数?
    这些函数各自都有什么特点?
    默认构造函数和复制构造函数
    默认构造函数:当没有定义一个默认构造函数时,系统会自动的给出一个默认构造函数
    复制构造函数:

    3. 什么是浅拷贝, 什么是深拷贝?
    浅拷贝:复制的只是要拷贝数据地址,没有拷贝数据内容
    深拷贝:这是申请一块新的内存地址,将原有的内容放到一个新申请的地址空间中去

    4. 实现一个自定义的String类,保证main函数对正确执行
    class String
    {
    public:
    String();
    String(const char *pstr);
    String(const String & rhs);
    String & operator=(const String & rhs);
    ~String();

    void print();

    private:
    char * _pstr;
    };

    string实现

    #include <iostream>
    #include <string.h>

    using std::cout;
    using std::endl;

    class String
    {
    public:
    String():_pstr(nullptr){
      //要给char *_pstr;赋予一个NULL
      cout << "_pstr = " << endl;
    }

    String(const char *pstr):_pstr(new char[strlen(pstr) + 1])
    {
      strcpy(_pstr,pstr);
      cout << "String(const char *pstr)" << endl;
    }

    String(const String & rhs):_pstr(new char[strlen(rhs._pstr) + 1]())
    {
      strcpy(_pstr,rhs._pstr);
      cout << "String(const String &rhs)" << endl;
    }
    String & operator=(const String & rhs)
    {
      cout << "String &operator=(const String &rhs)" << endl;
      _pstr = rhs._pstr;
      return *this;
    }
    ~String()
    {
      delete [] _pstr;
      cout << "~String" << endl;
    }

      void print();

    private:
      char * _pstr;
    };

    void String::print()
    {
      //cout << "_pstr = " << _pstr << endl;
      printf("_pstr = %s ",_pstr);
    }
    int main(void)
    {
      //String str1;//调用默认构造函数
      //str1.print();

      String str2 = "Hello,world";//调用构造函数String(const char *pstr)
      //String str3("wangdao");// 调用构造函数String(const char * pstr)

      //str2.print();
      //str3.print();

      //String str4 = str3; //调用复制构造函数
      //str4.print();

      //str4 = str2;

      //str4.print();

      return 0;
    }


    赋值构造函数

    #include <string.h>
    #include <iostream>
    using std::cout;
    using std::endl;


    class Computer
    {
    public:
      Computer(const char * brand, double price)
      : _brand(new char[strlen(brand) + 1]())
      , _price(price)
      {
        strcpy(_brand, brand);
        cout << "Computer(const char *, double)" << endl;
      }

      Computer(const Computer & rhs)
        : _brand(new char[strlen(rhs._brand) + 1]())
        , _price(rhs._price)
      {
        strcpy(_brand, rhs._brand);
        cout << "Computer(const Computer&)" << endl;
      }

      Computer & operator=(const Computer & rhs)
      { //三部曲
        cout << "Computer & operator=(const Computer &)" << endl;
        if(this != &rhs) {// 自复制
          delete [] _brand;//回收左操作数开辟的空间
          _brand = new char[strlen(rhs._brand) + 1]();//深拷贝
          strcpy(_brand, rhs._brand);

          this->_price = rhs._price;
        }
        return *this;
      }

    void print()
    {
      printf(" brand = %p ", _brand);
      cout << " brand:" << _brand << endl
      << " price:" << _price << endl;
    }

    ~Computer()
    {
      delete [] _brand;
      cout << "~Computer()" << endl;
    }

    private:
      char * _brand;
      double _price;
    };

    void test0()
    {
      Computer pc1("MateBook.....", 6666);
      cout << ">> pc1: " << endl;
      pc1.print();

        //用一个已经存在的对象初始化另一个新对象
      Computer pc2 = pc1; //拷贝构造函数(或者说复制构造函数)
      cout << ">> pc2: " << endl;
      pc2.print();

      Computer pc3("Thinkpad", 8888);
      cout << ">> pc3: " << endl;
      pc3.print();

      pc3 = pc1;
      //pc3.operator=(pc1);
      cout << ">> pc3: " << endl;
      pc3.print();


      pc2 = pc2;
    }

    int main(void)
    {
      test0();
      return 0;
    }


    静态成员函数


    #include <string.h>
    #include <iostream>
    using std::cout;
    using std::endl;


    class Computer
    {
    public:

      Computer(const char * brand, double price)
        : _brand(new char[strlen(brand) + 1]())
        , _price(price)
      {
        strcpy(_brand, brand);
        cout << "Computer(const char *, double)" << endl;
        _totalPrice += _price;
      }

      Computer(const Computer & rhs)
        : _brand(new char[strlen(rhs._brand) + 1]())
        , _price(rhs._price)
      {
        strcpy(_brand, rhs._brand);
        cout << "Computer(const Computer&)" << endl;
      }

      Computer & operator=(const Computer & rhs)
      { //三部曲
        cout << "Computer & operator=(const Computer &)" << endl;
        if(this != &rhs) {// 自复制
          delete [] _brand;//回收左操作数开辟的空间
          _brand = new char[strlen(rhs._brand) + 1]();//深拷贝
          strcpy(_brand, rhs._brand);

          this->_price = rhs._price;
        }
        return *this;
      }

      void print()
      {
        cout << " brand:" << this->_brand << endl
        << " price:" << this->_price << endl;
      }

      //静态成员函数没有隐含的this指针
      static void printTotalprice()
      {//静态成员函数内部不能非静态的成员
        //cout << " brand:" << this->_brand << endl
        cout << " total price: " << _totalPrice << endl;
      }

      ~Computer()
      {
        delete [] _brand;
        cout << "~Computer()" << endl;
      }

    private:
      char * _brand;
      double _price;
      //静态成员位于全局静态区, 被整个类所创建的所有对象共享
      static double _totalPrice;
    };

    //全局的位置进行初始化
    double Computer::_totalPrice = 0;

    void test0()
    {
      cout << "sizeof(Computer) = " << sizeof(Computer) << endl;
      Computer pc1("MateBook.....", 6666);
      cout << ">> pc1: " << endl;
      pc1.print();
      //pc1.printTotalprice();
      Computer::printTotalprice();

      Computer pc3("Thinkpad", 8888);
      cout << ">> pc3: " << endl;
      pc3.print();
      //pc3.printTotalprice();
      Computer::printTotalprice();//静态成员函数可以直接通过类名调用
    }

    int main(void)
    {
      test0();
      Computer::printTotalprice();
      return 0;
    }


    Empty class

    #include <iostream>
    using std::cout;
    using std::endl;

    class Empty
    {};

    int main(void)
    {
      Empty e1;
      Empty e2;
      &e1;
      &e2;
      cout << "sizeof(e1) = " << sizeof(e1) << endl; // 1
      return 0;
    }


    NullptrCall

    #include <iostream>
    using std::cout;
    using std::endl;

    class NullptrCall
    {
    public:
      void func1()
      { cout << "func1()" << endl; }

      void func2(int ix)
      { cout << "func2() ix = " << ix << endl; }

      static void func3()
      { cout << "func3()" << endl; }

      void func4()
      { cout << "func4() _ix " << this->_ix << endl; }

    private:
      int _ix;
    };

    int main(void)
    {
      NullptrCall * p = nullptr;

      p->func1();// NullptrCall::func1(nullptr);
      p->func2(10);//NullptrCall::func2(nullptr, 10);
      p->func3();//NullptrCall::func3();
      p->func4();//NullptrCall::fun4(nullptr);
      return 0;
    }


    const的成员函数

    #include <iostream>
    using std::cout;
    using std::endl;

    class Point
    {
    public:
      Point()
      : _ix(0)
      , _iy(0)
      {
        cout << "Point()" << endl;
      }

      Point(int ix, int iy)
      : _ix(ix)
      , _iy(iy)
      {
        cout << "Point(int,int)" << endl;
      }

      void setX(int ix)
      { _ix = ix; }


    #if 0
    void print(/* Point * const this */)
    {
      //非const版本的成员函数是可以修改成员的
      //this = 0x1000;
      _ix = 100;

      cout << "void print()" << endl;
      cout << "(" << this->_ix
      << "," << this->_iy
      << ")" << endl;
    }
    #endif

      //以后只要某一个函数不会对数据成员进行修改,都要将其设置为
      //const成员函数
    #if 1
    void print(/* const Point * const this */) const
    {
      //_ix = 100;//error
      cout << "void print() const" << endl;
      cout << "(" << this->_ix
      << "," << this->_iy
      << ")" << endl;
    }
    #endif

    ~Point()
    {
      cout << "~Point()" << endl;
    }

    private:
      int _ix;
      int _iy;
    };

    void func1(const Point & rhs)
    {
      rhs.print();
    }



    int main(void)
    {

      //Point pt1(1, 2);//非const对象调用的是非const成员函数
      //cout << "pt1 = ";//非const对象也可以调用const成员函数
      //pt1.print();

      //const Point pt2(3, 4);//const对象只能调用的const成员函数
      //pt2.print();

      //func1(pt1);

    Point points[5] = {
      Point(1, 2),
      Point(3, 4)
    };

      points[0].print();
      points[2].print();

      return 0;
    }


    单例设计模式

    #include <iostream>
    using std::cout;
    using std::endl;

    //要求: 通过某一个类在内存中只能创建唯一的一个对象
    //
    //1. 该对象不能是栈(全局)对象
    //2. 该对象只能是一个堆对象
    //

    //单例模式的应用场景有:
    //1. 单例模式替换全局变量
    //2. 配置文件的内容可以用单例对象存储
    //3. 词典文件、网页库

    class Singleton
    {
    public:
    static Singleton * getInstance()
    {
      if(_pInstance == nullptr) {
        _pInstance = new Singleton();
      }
      return _pInstance;
    }

    static void destroy()
    {
      if(_pInstance)
        delete _pInstance;
    }

    void print() const
    {
      cout << "Singleton::data = " << _data << endl;
    }
    private:
      Singleton():_data(0){ cout << "Singleton()" << endl; }
      ~Singleton(){ cout << "~Singleton()" << endl; }

    private:
      int _data;
      static Singleton * _pInstance;
    };

    Singleton * Singleton::_pInstance = nullptr;

    //Singleton s3;

    int main(void)
    {
      //Singleton s1;//与要求不符合,该语句不能让他编译通过
      //s1.print();
      //Singleton s2;
      //s2.print();

      //Singleton * p = new Singleton();

      Singleton * p1 = Singleton::getInstance();
      Singleton * p2 = Singleton::getInstance();

      Singleton::getInstance()->print();

      cout << "p1 = " << p1 << endl
        << "p2 = " << p2 << endl;

      //delete p1;//该语句不能让他编译通过
      //delete p2;//error

      Singleton::destroy();

      return 0;
    }


    IO

    #include <iostream>
    #include <string>
    #include <limits>
    using std::cout;//std::ostream
    using std::cin;
    using std::endl;
    using std::string;


    void printStreamStatus()
    {
      cout << "cin's badbit = " << cin.bad() << endl
        << "cin's failbit = " << cin.fail() << endl
        << "cin's eofbit = " << cin.eof() << endl
        << "cin's goodbit = " << cin.good() << endl;
    }

    void test0()
    {
      int number;
      printStreamStatus();
      while(cin >> number) {
        printStreamStatus();
        cout << ">> number = " << number << endl;
      }
      printStreamStatus();

      cout << "clear之后, 流的状态:" << endl;
      cin.clear();//重置流的状态
      cin.ignore(1024, ' ');//清空缓冲区

      printStreamStatus();

      string str;
      cin >> str;
      cout << "str = " << str << endl;
    }


    void test1()
    {
      cout << "pls input a interger number:" << endl;
      int number;
      while(cin >> number, !cin.eof()) {
        if(cin.bad()) {
          cout << ">> cin stream status is corrupted!" << endl;
          return;
        } else if(cin.fail()) {
          cout << "pls input a valid interger number:" << endl;
          cin.clear();
          cin.ignore(std::numeric_limits<std::streamsize>::max(), ' ');
          continue;
        }

      cout << ">> number = " << number << endl;
      }

      printStreamStatus();
    }


    int main(void)
    {
      //test0();
      test1();
      return 0;
    }


    文件IO操作

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    using std::cin;
    using std::cout;
    using std::endl;
    using std::fstream;
    using std::ifstream;
    using std::ofstream;
    using std::string;
    using std::vector;

    vector<string> file;

    void test1()
    {
      //ifstream要求文件必须存在
      //ifstream ifs("test.txt");
      ifstream ifs("io2.cc");
      if(!ifs.good()) {
        cout << "ifstream open file error!" << endl;
        return;
      }

      file.reserve(100);
      string line;
      //while(ifs >> str) {
      while(std::getline(ifs, line)) {
        file.push_back(line);  
      }

      //auto 自动推导元素的类型
    #if 0
      for(auto & line : file)
      {
        cout << line << endl;
      }
    #endif

      ifs.close();
    }

    void test2()
    {
      string filename = "test.txt";
      //文件输出流不要求文件存在;
      //当文件不存在时,直接创建文件;
      //当文件存在时,直接清空文件中的内容
      ofstream ofs(filename);
      if(!ofs.good()) {
        cout << ">> ofstream open error!" << endl;
        return ;
      }

      for(auto & line : file)
      {
        ofs << line << " ";
      }
      ofs.close();
    }

    void test3()
    {
      string filename = "test.txt";
      //std::ios::app模式可以在文件的末尾追加新的内容
      ofstream ofs(filename, std::ios::app);
      if(!ofs.good()) {
        cout << ">> ofstream open error!" << endl;
        return ;
      }

      cout << "pos: " << ofs.tellp() << endl;

      string line = "that's a new line ";
      ofs << line;

      ofs.close();
    }

    void printStreamStatus(fstream & fs)
    {
      cout << "fs's badbit = " << fs.bad() << endl
        << "fs's failbit = " << fs.fail() << endl
        << "fs's eofbit = " << fs.eof() << endl
        << "fs's goodbit = " << fs.good() << endl << endl;
    }

    void test4()
    {
      string filename = "readme.txt";
      fstream fs(filename);
      if(!fs.good()) {
        cout << "fstream open error! " << endl;
        return ;
      }

      int number = -1;
      for(size_t idx = 0; idx != 10; ++idx)
      {
        cin >> number;
        fs << number << " ";
      }
      cout << ">> pos : " << fs.tellg() << endl;
      fs.seekg(std::ios::beg);

      printStreamStatus(fs);
      for(size_t idx = 0; idx != 10; ++idx)
      {
        fs >> number;

        //printStreamStatus(fs);
        cout << number << " ";
      }
      cout << endl;

      fs.close();
    }

    void test5()
    {
      string filename = "vector.cc";
      ifstream ifs;
      ifs.open(filename, std::ios::in|std::ios::ate);
      if(!ifs.good()) {
        cout << ">> ifstream open file error!" << endl;
        return;
      }

      cout << "pos: " << ifs.tellg() << endl;
      size_t len = ifs.tellg();

      char buff[len + 1] = {0};

      ifs.seekg(std::ios::beg);

      ifs.read(buff, len);//获取一篇文章的内容

      cout << "buff:" << endl << buff << endl;

      ifs.close();
    }



    int main(void)
    {
      //test1();
      //test2();
      //test3();
      //test4();
      test5();
      return 0;
    }


    string IO 

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <fstream>
    #include <vector>
    using std::cout;
    using std::endl;
    using std::string;
    using std::vector;
    using std::ifstream;
    using std::stringstream;
    using std::istringstream;
    using std::ostringstream;

    void printStreamStatus(stringstream & fs)
    {
      cout << "fs's badbit = " << fs.bad() << endl
        << "fs's failbit = " << fs.fail() << endl
        << "fs's eofbit = " << fs.eof() << endl
        << "fs's goodbit = " << fs.good() << endl << endl;
    }

    void test0()
    {
      int number1 = 1;
      int number2 = 2.22;

      stringstream ss;

      //字符串输出流
      ss << "number1= " << number1 << " number2= " << number2;
      cout << ss.str() << endl << endl;
      //snprintf();

      string key;
      int value;

      while(!ss.eof()) {
        ss >> key >> value;
        //printStreamStatus(ss);
        cout << key << " ---> " << value << endl;
      }
    }

    string int2str(int number)
    {
      ostringstream oss;
      oss << number;
      return oss.str();
    }

    struct Element
    {
      Element(const string & k, const string & v)
      : key(k), value(v)
      {}
      string key;
      string value;
    };

    void readConfiguration(const string & filename)
    {
      ifstream ifs(filename);
      if(!ifs.good()) {
        cout << ">> ifstream open " << filename << " error!" << endl;
        return ;
      }

      vector<Element> config;

      string key, value;
      string line;
      while(getline(ifs, line)) {
        istringstream iss(line);
        while(!iss.eof()) {
          iss >> key >> value;
          //cout << key << " --> " << value << endl;
          Element element(key, value);
          config.push_back(element);
        }
      }

      for(auto & element: config)
      {
        cout << element.key << " ---> " << element.value << endl;
      }
    }

    void test1()
    {
      string filename = "my.conf";
      readConfiguration(filename);
    }

    int main(void)
    {
      //test0();
      test1();

      return 0;
    }


    vector

    #include <iostream>
    #include <vector>
    using std::cout;
    using std::endl;
    using std::vector;

    void printVectorCapacity(const vector<int> & c)
    {
      cout << "c's size = " << c.size() << endl;
      cout << "c's capacity = " << c.capacity() << endl;
    }


    int main(void)
    {
      int arr[10];//静态数组
      //动态数组
      //策略: 当数组中的size() == capacity(),并且此时还要
      //添加新的元素时,需要进行动态扩容。
      //
      //先去申请2 * capacity() 的空间,然后把原来空间中的
      //元素全部复制到新空间中,
      //然后去释放原来的空间的数据
      //最后再添加新的元素
      vector<int> numbers;
      numbers.reserve(100);
      printVectorCapacity(numbers);

      numbers.push_back(1);
      printVectorCapacity(numbers);
      numbers.push_back(1);
      printVectorCapacity(numbers);
      numbers.push_back(1);
      printVectorCapacity(numbers);
      numbers.push_back(1);
      printVectorCapacity(numbers);
      numbers.push_back(1);
      printVectorCapacity(numbers);
      numbers.push_back(1);
      printVectorCapacity(numbers);

      numbers.pop_back();

      for(size_t idx = 0; idx != numbers.size(); ++idx)
      {
        cout << numbers[idx] << " ";
      }
      cout << endl;

      //C++11中的
      for(auto & number : numbers)
      {
        cout << number << " ";
      }
      cout << endl;

      //迭代器访问
      auto iter = numbers.begin();
      while(iter != numbers.end())
      {
        cout << *iter << " ";
        ++iter;
      }
      cout << endl;

      return 0;
    }


    //要求: 只能生成堆对象,不能生成栈对象

    #include <string.h>
    #include <stdlib.h>

    #include <iostream>
    using std::cout;
    using std::endl;

    //要求: 只能生成堆对象,不能生成栈对象
    //解决方案:
    // 将析构函数放入private区域, 同时
    //还需要定义一个destroy方法, 在destroy方法
    //中去执行delete表达式

    class Student
    {
    public:
      Student(int id, const char * name)
      : _id(id)
      , _name(new char[strlen(name) + 1]())
      {
        strcpy(_name, name);
        cout << "Student(int, const char *)" << endl;
      }

      void print() const
      {
        cout << "(" << _id << ", " << _name << ")" << endl;
      }

      //提供一个接口,可以自定义开辟空间的方式
      //放在类内部,只针对于Student类型起作用
      //放在类之外,对所有的类型都会起作用
      static void * operator new(size_t sz)
      {
        cout << "void * operator new(size_t) " << endl;
        return malloc(sz);
      }

      static void operator delete(void * pointer)
      {
        cout << "void operator delete(void*)" << endl;
        free(pointer);
      }


      void destroy()
      {
        //this->~Student();
        delete this;
      }


    private:
      ~Student()
      {
        delete [] _name;
        cout << "~Student()" << endl;
      }

    private:
      int _id;
      char * _name;
    };

    int main(void)
    {
      Student * pstu = new Student(100, "Jackie");//ok
      pstu->print();
      //delete pstu;//error
      pstu->destroy();

      // Student stu(101, "John");//error
      // stu.print();

      return 0;
    }


    //只能生成栈对象, 不能生成堆对象

    #include <string.h>
    #include <stdlib.h>

    #include <iostream>
    using std::cout;
    using std::endl;

    //只能生成栈对象, 不能生成堆对象
    //
    //解决方案: 将operator new放入private区域
    //
    class Student
    {
    public:
      Student(int id, const char * name)
      : _id(id)
      , _name(new char[strlen(name) + 1]())
      {
        strcpy(_name, name);
        cout << "Student(int, const char *)" << endl;
      }

      void print() const
      {
        cout << "(" << _id << ", " << _name << ")" << endl;
      }

      ~Student()
      {
        delete [] _name;
        cout << "~Student()" << endl;
      }

    private:
      static void * operator new(size_t sz);
      static void operator delete(void * pointer);

    private:
      int _id;
      char * _name;
    };

    int main(void)
    {
      Student s1(101, "John");
      s1.print();

      //Student * pstu = new Student(100, "Jackie");//error
      //pstu->print();

      //delete pstu;
      return 0;
    }

  • 相关阅读:
    WC命令
    dcoker machine
    linux命令
    Valgrind 检测程序内存使用
    golang flag
    面试之---二叉树的遍历
    FFMpeg 版本错误
    C++中namespace的使用
    QT之QStatusBar
    建立ftp服务器和客户端
  • 原文地址:https://www.cnblogs.com/Davirain/p/11788862.html
Copyright © 2011-2022 走看看