C++学习

作者: arkliu | 来源:发表于2018-07-29 16:41 被阅读0次

输入输出

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

int main(void) {
    
    cout<< "请输入一个整数:"<< endl;
    int x = 0;
    cin >> x;
    cout << oct << x << endl;
    cout << dec << x << endl;
    cout << hex << x << endl;    
    
    cout<< "请输入一个bool值:"<< endl;
    bool y = false;
    cin >> y;
    cout << boolalpha << y << endl; 
        
    system("pause");
    return 0;
}

执行如下:


1.png

命名空间

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

namespace A {
   int x = 1;
   void fun() {
        cout << "A" << endl;     
   }
}

namespace B {
   int x = 2;
   void fun() {
        cout << "B" << endl;     
   }
   
   void fun2() {
       cout << "2B" << endl;     
   }
}

using namespace B;
int main(void) {
    cout << A::x <<endl;
    B::fun();
    B::fun2();       
    fun2();
    
    system("pause");
    return 0;
}

2.png

有了上面的代码学习,如果没有引入std的命名空间,我们的输入输出函数还可以这样写

#include <iostream>
#include <stdlib.h>

int main(void) {
    
    std::cout << "请输入一个bool值:"<< std::endl;
    bool y = false;
    std::cin >> y;
    std::cout << std::boolalpha << y << std::endl; 
        
    system("pause");
    return 0;
}

3.png

可以看到上面并没有引入std的命名空间,而是在每次使用std命名空间里的函数时候,前面主动加上std

案例1

定义一个函数,函数功能是找出一个数组中的最大值和最小值

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

int getMaxOrMin(int * arr, int count, bool isMax) {
    int temp = arr[0];
    for (int i = 1; i < count; i++) {
        if (isMax) {
            if (temp < arr[i]) {
                temp = arr[i];         
            }     
        } else {
            if (temp > arr[i]) {
                temp = arr[i];         
            }
        }
    }    
    return temp;
}

int main(void) {
    int arr[4] = {4,7,8,2};
    bool isMax = false;
    cin >> isMax;
    cout << getMaxOrMin(arr, 4, isMax) << endl; 
    system("pause");
    return 0;
}

4.png

const关键字

#includ

e <iostream>
#include <stdlib.h>
using namespace std;


int main(void) {
    const int x = 3; // 添加const 关键字,表示不可变,类似于java的final 
    // x = 5;  // 编译错误,提示x为readonly 
    
    int const * p = &x;
    // *p = 5;  // 编译错误,提示x为readonly 
    
    int y = 5;
    int * const p = &x;  
    // p = &y; // 编译错误, 'p' has a previous declaration as `const int*p' 
    
    
    
    system("pause");
    return 0;
}

函数参数默认值

C++中,有默认参数值的参数,必须在参数表的最右端,比如:

void fun(int x, int y = 10, int k) // 错误
void fun(int x, int y, int k=10) // 正确

看下面代码:

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

void fun(int x= 100, int y=200, int k = 300);

void fun(int x, int y, int z) {
     cout << x << "--" << y << "--" << z << endl;     
}

int main(void) {   
    
    fun();
    fun(20);
    fun(29, 30);
    fun(40, 50, 60);
    
    system("pause");
    return 0;
}

5.png

分配和释放内存

指针内存使用完成以后,需要使用delete关键字释放,并且把对应的变量,置为NULL

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

int main(void) {   
    int * p = new int[1000];
    if (p == NULL) {
           cout << "分配内存失败" << endl; 
           system("pause");
           return 0;   
    } 
    p[0] = 10;
    p[1] = 20;
    cout << "p[0] is :" << p[0] << "p[1] is :" << p[1] << endl;
    delete []p;
    p = NULL;
    
    system("pause");
    return 0;
}

类和对象的定义

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

class Position {
  
  public:
          int x;
          int y;
          
          void printX() {
               cout << "x is :" << x << endl;      
          }
          void printY() {
               cout << "y is :" << y << endl;      
          }
      
};


int main(void) {   

    Position position;
    position.x = 10;
    position.y = 30;
    position.printX();
    position.printY();
    
    Position * p = new Position();
    p->x = 33;
    p->y = 44;
    p->printX();
    p->printY();
    
    system("pause");
    return 0;
}

6.png

类外定义代码

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

class Teacher {
  
  private:
     int mAge;
     string mName;
     string mGender; 
  public:
     void setAge(int age);
     void setName(string name);
     void setGender(string gender);
     int getAge();
     string getName();
     string getGender();
     void teach();
};

int Teacher::getAge() {
   return mAge;  
}

string Teacher::getGender() {
   return mGender;       
}

string Teacher::getName() {
   return mName;       
}

void Teacher::setAge(int age) {
   mAge = age;     
}

void Teacher::setGender(string gender) {
   mGender = gender;     
}

void Teacher::setName(string name) {
   mName = name;     
}

void Teacher::teach() {
    cout << "正在上课..." << endl;     
}


int main(void) {   

    Teacher teacher;
    teacher.setAge(40);
    teacher.setName("小王");
    teacher.setGender("男");
    
    cout << teacher.getName() << teacher.getGender() << teacher.getAge() << endl;
    teacher.teach();
    
    system("pause");
    return 0;
}

7.png

构造函数

上述代码增加构造有参数和无参构造方法,修改如下:

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

class Teacher {
  
  private:
     int mAge;
     string mName;
     string mGender; 
  public:
     void setAge(int age);
     void setName(string name);
     void setGender(string gender);
     int getAge();
     string getName();
     string getGender();
     void teach();
     
     Teacher();
     Teacher(string name, string gender, int age); 
};

int Teacher::getAge() {
   return mAge;  
}

Teacher::Teacher(){}

Teacher::Teacher(string name, string gender, int age) {
     mAge = age;
     mName = name;
     mGender = gender;
     cout << "Teacher::Teacher(string name, string gender, int age)" << endl;                        
}

string Teacher::getGender() {
   return mGender;       
}

string Teacher::getName() {
   return mName;       
}

void Teacher::setAge(int age) {
   mAge = age;     
}

void Teacher::setGender(string gender) {
   mGender = gender;     
}

void Teacher::setName(string name) {
   mName = name;     
}

void Teacher::teach() {
    cout << "正在上课..." << endl;     
}


int main(void) {   

    Teacher teacher;
    teacher.setAge(40);
    teacher.setName("小王");
    teacher.setGender("男");
    
    cout << teacher.getName() << teacher.getGender() << teacher.getAge() << endl;
    teacher.teach();
    
    Teacher teacher_second("小李", "女", 89);
    cout << teacher_second.getName() << teacher_second.getGender() << teacher_second.getAge() << endl;
    teacher_second.teach();
    
    system("pause");
    return 0;
}

8.png

拷贝构造函数

  • 如果没有定义拷贝构造函数,则系统自动生成一个默认的拷贝构造函数
  • 当采用直接初始化,或复制初始化实例对象时候,系统自动调用拷贝构造函数
#include <iostream>
#include <stdlib.h>
using namespace std;

class Student {
  
  private:
     int mAge;
     string mName;
     string mGender; 
  public:
     void setAge(int age);
     void setName(string name);
     void setGender(string gender);
     int getAge();
     string getName();
     string getGender();
     void teach();
     
     Student();
     Student(string name, string gender, int age);  // 定义有参数构造函数 
     Student(const Student &stu); // 定义拷贝构造函数 
};

Student::Student(){}

Student::Student(string name, string gender, int age) {
     mAge = age;
     mName = name;
     mGender = gender;
     cout << "有参数构造函数 name is :" << name << endl;                        
}

Student::Student(const Student &stu){
     cout << "拷贝构造函数" << endl;                              
} 



int main(void) {   

    Student student1("张三" , "男" , 44); 
    Student student2("李四" , "男" , 33);
    Student student3 = student2; 
    Student student4(student1);
    
    system("pause");
    return 0;
}

9.png

析构函数

定义格式

~ 类名();

如果没有析构函数,则由系统自动生成,需要注意的是,析构函数没有参数,不能重载

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

class Student {
  
  private:
     int mAge;
     string mName;
     string mGender; 
  public:
     Student(string name, string gender, int age);  // 定义有参数构造函数 
     ~Student(); // 定义析构函数 
};

Student::Student(string name, string gender, int age) {
     mAge = age;
     mName = name;
     mGender = gender;
     cout << "有参数构造函数 name is :" << name << endl;                        
}

Student::~Student() {  // 实现析构函数 
     cout << "析构函数....." << endl;           
}



int main(void) {   

    Student student1("张三" , "男" , 44); 
    Student *p = new Student("王五", "女" , 23);
    delete p;
    
    system("pause");
    return 0;
}

10.png

浅拷贝

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

class Array {
      
      public:
             Array(); // 定义构造函数 
             Array(const Array &arr);  // 定义拷贝构造函数 
             ~Array(); // 定义析构函数 
             void setCount(int count);
             int getCount();
      private:
             int m_count;
};


Array::Array() {
    cout << "Array 构造函数runs..." << endl;              
}

Array::Array(const Array &arr) {
    m_count = arr.m_count;    
    cout << "Array 拷贝构造函数runs..." << endl;              
} 

Array::~Array() {
    cout << "Array 析构函数runs..." << endl;      
}

void Array::setCount(int count) {
    m_count = count;                    
}

int Array::getCount() {
    return m_count;                  
}




int main() {
    
    Array arr1;
    arr1.setCount(5);
    
    Array arr2(arr1);
    
    cout << "arr2 m_count is :" << arr2.getCount() << endl;
    
    
    system("pause");
    return 0;
}

上述代码中,首先构造arr1,对象,在通过arr1构造arr2对象,此时,会执行拷贝构造函数,并且将arr1的m_count赋值给了arr2对象,执行结果如下:


11.png

深拷贝

首先申请一段内存,然后将需要拷贝的对象中指向的一段内存的值,赋值给一开始申请的内存地址中

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

class Array {
      
      public:
             Array(int count); // 定义构造函数 
             Array(const Array &arr);  // 定义拷贝构造函数 
             ~Array(); // 定义析构函数 
             void setCount(int count);
             int getCount();
             void printAddr();
             void printArr();
      private:
             int m_count;
             int * m_parr; 
};


Array::Array(int count) {
    m_count = count;
    m_parr = new int[m_count]; //申请一段内存
    for (int i = 0; i < m_count; i++) { // 为数组对象赋值 
        m_parr[i] = i;    
    } 
    cout << "Array 构造函数runs..." << endl;              
}

Array::Array(const Array &arr) {
    m_count = arr.m_count;
    m_parr = new int[m_count]; 
    for (int i = 0; i < m_count; i++) {
        m_parr[i] = arr.m_parr[i];    
    }
    cout << "Array 拷贝构造函数runs..." << endl;              
} 

Array::~Array() {
    delete [] m_parr;
    m_parr = NULL;
    cout << "Array 析构函数runs..." << endl;      
}

void Array::setCount(int count) {
    m_count = count;                    
}

int Array::getCount() {
    return m_count;                  
}

void Array::printAddr() {
     cout << m_parr << endl;
}

void Array::printArr() {
    for (int i = 0; i < m_count; i++) {
        cout << m_parr[i] << endl;    
    }
}




int main() {
    
    Array arr1(6);
    Array arr2(arr1);
    
    arr1.printAddr();
    arr2.printAddr();
    
    arr1.printArr();
    arr2.printArr();
    
    cout << "arr2 m_count is :" << arr2.getCount() << endl;
    
    
    system("pause");
    return 0;
}

12.png

公有继承

公有继承中:

  • 基类的共有成员就相当于是派生类的公有成员,也就是说派生类可以像访问自身公有成员一样访问从基类继承的公有成员。
  • 基类的保护成员就相当于是派生类的保护成员,即,派生类可以像访问自身的保护成员一样,访问基类的保护成员。
  • 对于基类的私有成员,派生类内部成员是无法直接访问的,派生类使用者也无法通过派生类对象直接访问。

换言之:
当类的继承方式为公有继承时,基类中的公有(public)成员和保护(protected)成员的访问权限在派生类中保持不变,而基类的私有成员不可访问,也就是说:基类的公有成员和保护成员被派生类继承过来作为派生类的公有和保护

成员,而基类的私有成员在派生类中不能直接使用。

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

class Person {
    public:
           Person();
           ~Person();
           void eat();
           int age;
           string name;    
};

Person::Person() {
    cout << "Person" << endl;             
}

Person::~Person() {
    cout << "~Person" << endl;                                
}

void Person::eat() {
    cout << "eat" << endl;             
}



class Worker : public Person {
      public:
             Worker();
             ~Worker();
             void work();
             int salary;
      
};

Worker::Worker() {
    cout << "Worker" << endl;                     
}

Worker::~Worker() {
    cout << "~Worker" << endl;                  
}

void Worker::work() {
    cout << "work" << endl;               
}


int main() {
    
    Worker * p = new Worker();
    p->age = 34;
    p->name = "lisi";
    p->eat();
    p->salary = 8000;
    p->work();
    delete p;
    p = NULL;
    
    
    
    system("pause");
    return 0;
}

上述代码中,Worker继承自Person类

  • 在构造子类的时候,父类的构造函数会先执行,而后执行子类的构造函数
  • 在释放内存时候,会先执行子类的析构函数,后执行父类的析构函数
    运行结果如下:


    13.png

保护继承和私有继承

  • 创建Person类
  • 创建Solider类,继承自Person
  • 创建Infantry 类继承自Solider
#include <iostream>
#include <stdlib.h>
using namespace std;

class Person {
    public:
           Person();
           void play();
    protected:
           string name;    
};

Person::Person() {
    name = "lisi";
    cout << "Person contruct" << endl;             
}

void Person::play() {
    cout << "Person play" << endl;             
    cout << "name is :" << name << endl;        
}



class Solider : public Person {
      public:
             Solider();
             void work();
             int age;
      
};


void Solider::work() {
     name = "王五";
     age = 23;
    cout << name << endl;     
    cout << age << endl;     
    cout << "work" << endl;               
}


Solider::Solider() {
    cout << "Solider construct" << endl;                     
}


class Infantry : public Solider {
    public:
        void attrack();      
};

void Infantry::attrack() {
       cout << "Solider attrack" << endl;  
} 


int main() {
    
    Solider solider;
    solider.work(); 
    
    system("pause");
    return 0;
}

此时执行结果如下:


14.png
  • 基类的公有成员和保护成员都相当于派生类的保护成员,派生类可以通过自身的成员函数或其子类的成员函数访问它们。
  • 对于基类的私有成员,无论派生类内部成员或派生类的对象都无法直接访问

私有继承

  • 基类成员对其对象的可见性:

公有成员可见,其他成员不可见。

  • 基类成员对派生类的可见性:

公有成员和保护成员是可见的,而私有成员是不可见的。

  • 基类成员对派生类对象的可见性:

所有成员都是不可见的。

所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。

相关文章

网友评论

      本文标题:C++学习

      本文链接:https://www.haomeiwen.com/subject/zcxtvftx.html