c++ 2 知识点

来源:互联网 发布:你不知道的事 知乎 编辑:程序博客网 时间:2024/06/10 17:05

C++

namespace

cin cout
cout<< hex or oct or dec     十六进制 八进制 十进制
cout<<showpoint             显示小数点
cout<<noshowpoint

cout << fixed       显示定点数  d.ddddd格式
cout.unsetf(ios_base::fixed); 取消定点数显示
cout << setprecision(3)  在设置了fixed之后设置显示精度,表示显示3位小数
cout << setw(6)     显示宽度为6位, 这个仅仅生效一次, 生效完毕后自动为setw(0)

cout << setfill('0')  设置填充字符,默认为空格字符
cout << left    左对齐
cout << right   右对齐 默认是右对齐

cout << boolalpha    显示布尔值为字符形式
cout << scientific   显示小数为科学记数法格式 0.037608  ===> 3.760800e-02

运算符重载的知识点:

1、可以被重载的运算符有
new        new[]        delete    delete[]
+  -  *  /  %  ^  &  |  ~  !  =  <  >  +=  -=  *=  /=  %=  
^=  &=  |=  <<  >>  <<=  >>=  ==  !=  <=  >=  &&  ||  ++  
--  ,  ->*  ->  ()  []
其中,+  -  *  &  的一元、二元形式都可以被重载,自增运算符++和自减运算符--的前置、后置形式都可以被重载。

2、不可以被重载的运算符有:
成员选择符.     成员对象选择符.*      域解析操作符::      条件操作符?:

3、一般来说,运算符可以有两种重载方式:
    a、可以用类的成员函数形式来重载
        a+b     ====>     a.operator+(b)   通常只有1个参数
    b、可以用不属于类的顶层函数形式来重载,通常会声明成类的friend友元函数,
    这将至少带有一个类对象参数,否则都是内建类型(如2+3,就不需要重载运算符了)。
        a+b     ====>     operator+(a, b)  通常要有2个参数
    c、operator<<只能以顶层函数形式重载,如果重载为类的成员函数,那么就只能是ostream类的成员函数,但是我们不能修改系统的源码,所以只有重载成顶层函数的形式了。

4、下标操作符[]、赋值操作符=、函数调用操作符()和指针操作符->必须以类的成员函数的形式重载。

5、下标运算符的重载形式一般有两种:
    可读写数组元素
    class A{
        //...
        returntype& operator[](paramtype);
        //...
    };

    只读方式
    class A{
        //...
        const returntype& operator[](paramtype) const;
        //...
    };
    
6、自增++
        前置++a
        operator++();
    and    
        后置a++
        operator++(int); //参数没有用它,只是用来区分前后置的。

异常处理:    
try{
    cout << c[2] << endl;
}
catch(string except){
    if(except == "outofrange")
    {
        cerr << "your array index is out of range!" << endl;
        exit(1);
    }
}

static成员变量:
1、它是整个类共有的,只有1份拷贝。
    class A{
        static int i;
    };
    int A::i;
    int main()
    {
        A a, b;
        a.i = 10;
        b.i = 20;
        cout << a.i << b.i;
        结果应该都是20
    }
2、它既可以象普通成员变量一样去访问,也可以直接使用类名去访问。
    A a;  a.i = 100;
    A::i = 100;

static成员函数:
1、它既可以象普通成员函数一样用对象去调用,也可以直接使用类名去调用。
    A a;   a.display();
    A::display();
2、它只能访问静态成员变量,不能访问普通成员变量。


int main()
{
    Person a("xiaoming", 12); //在main函数栈上创建的a对象,不用我们回收,栈会自动回收它的空间
    a.display();

    //在堆上创建了一个Person类的对象,需要我们自己去回收,使用delete回收它的空间
    Person *pa = new Person("xiaoming", 12);
    pa->display();
    delete pa;

     return 0;
}

static静态成员变量
它是属于整个类所共有的数据,类中只有唯一的一份,大家都一样。通过这个类的每一个对象去访问它都会让别的对象知道这个改变。
静态成员变量不属于具体的某一个对象,而是属于整个类,所以它不存储在对象的数据中,存在静态存储区中。
访问静态成员变量的方法和普通成员变量有区别
    普通成员变量:先创建对象,然后由对象和成员选择符"."才能去访问,比如
    A a;
    a.age = 10;

    静态成员变量:可以象普通成员变量一样用对象名和成员选择符一样去访问,还可以不创建对象,一样能访问。
    A::age = 10;
 
静态成员函数不能访问普通成员变量,只能访问静态成员变量;普通成员函数两者都能访问
静态成员函数和静态成员变量类似,它属于整个类所共有,可以不创建这个类的对象就调用它。
    A::goo();
    类比下普通成员函数的调用
    A a;
    a.foo();

C里的static有什么含义?
一个不属于类的局部变量加了static,变量生命期延长了,整个程序的生命期,但是作用域不变,仍旧是局部变量。
一个不属于类的全局变量前加static,变量生命期不变,但是作用域改变为只能在本文件中使用。
一个不属于类的函数前加上static,函数只能被本目标文件范围内的函数调用,不能被其他文件调用。

 
the big three


继承
class A{
    //...
};//基类

class B : public A{
    //...
};//派生类

父类指针可以指向子类对象
但是子类指针不可指向父类对象,强制如此的话,访问会不安全。

子类里面实现了一个和父类里的函数同名的一个新函数的话,这称为子类的这个函数遮住了父类的同名函数.遮挡不会去查看参数数否一致,只关心函数名字是否一样,一样就遮住hide(隐藏)了。

在类定义时:
class A{
public:    //公有的  被属于这个类的函数访问,也可以被不属于这个类的其他类的函数访问,还可以被象main函数那样不属于任何类的顶层函数访问。
    //...
    int a;
    void goo();

protected:  //保护的  可以被属于这个类的成员函数访问,也可以被派生类的函数访问,但除此以外的其他类的成员函数以及main函数之类的顶层函数都不能访问protected成员。
    //...
    int b;
    void hoo();    

private:    //私有的  只能被属于这个类的成员函数访问。派生类也是一个新的类型,派生类的成员函数也不能访问private的成员,main函数之类的顶层函数更不能访问到private成员了。
    //...
    int c;
    void foo();
};

int main()
{
    A obj;
    obj.a = 10;//ok! public
    obj.goo(); //ok! public
    obj.c = 10; //error!  private
    obj.foo(); //error!  private
}


继承时的方法,也分成了三种 public   protected    private
class A{
public:
    int a;
    void foo();

protected:
    int b;

private:
    int c;
};

public方式继承
class B : public A{
//以下是B类自己的函数
    void goo();

//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a;  //public
int A::b;  //protected
int A::c;  //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};

protected方式继承
class B : protected A{
//以下是B类自己的函数
    void goo();

//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a;  //protected
int A::b;  //protected
int A::c;  //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};

private方式继承
class B : private A{
//以下是B类自己的函数
    void goo();

//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a;  //private
int A::b;  //private
int A::c;  //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};

一个常见的问题:
请你讲讲C++中overload、override、hide之间有什么区别?
overload 重载
    在同一个类,或者同一个区域(顶层函数),函数的名字相同,但是函数的参数不同(包括参数类型和个数不同),这个称为重载,比如
    int add(int a, int b);
    double add(double a, double b);
    类中的构造函数重载
    class A{
    public:
        A();
        A(int a);
        A(const A& a); //拷贝构造函数
    };

override 重写或覆盖
    override是指在不同区域中(父类、子类区域不同),有一模一样的函数(返回值、函数名、参数列表都要一样),同时这些函数都有virtual关键字,这时称为子类的这些函数覆盖或重写了(override)父类的同名函数。当调用这些同名函数的时候,依据对象的真实类型(而不是指向对象的指针类型),调用对应类型里的函数实现。
    比如:多态的例子

hide 隐藏、遮住
    当调用这些同名函数的时候,依据指向对象的指针类型(栈上创建的对象,依据对象类型),调用对应类型里的函数实现。
    hide和override的共同点:
    函数分别在父类、子类的不同区域。

    hide和override类似,仅仅有如下两个地方不同:
    a、hide针对的是没有virtual的非虚函数
    b、hide的函数即使参数列表不一样,但只要函数名一样,也构成隐藏。
    比如:
    class A{
    public:
        void foo();
    };
    
    class B:public A{
    public:
        void foo(int a);//隐藏了父类的A::foo()函数,即使参数不同。
        void foo();  //一样隐藏了父类的A::foo()函数
    };
    




原创粉丝点击