《类》

1.构造函数相关知识点

1.1.类的构造函数默认值

class box{
    int h;
    int l;
    int w;

    box();
    box(int h = 1, int l = 1, int w = 1);
};

  上面对应了2个构造函数,第二个构造函数带有默认初始化值。但是对于编译器来讲,这是属于一个函数定义,所以用这个类去实例化对象会报错。

1.2 在构造函数中使用初始化列表

初始化列表:
box::box(int h, int l, int w) : height(h), length(l), width(w)
{    
}
参数正常赋值:
box::box(int h, int l, int w)
{
    height = h;
    length = l;
    width = w;
}

  参数正常复制:首先创建该数据成员,再执行赋值语句。

  初始化列表:函数成员在创建时,就用初始值对它进行初始化。

  所以在效率方面,初始化表列要高得多,尤其是在数据成员是一个类实例时。

  

委托语法:

class Ageing:public wmt::WmtThread
{
public:
    Ageing(bool ui): WmtThread("Ageing") {
        init(ui);
    }
    Ageing():Ageing(true){
    };
  略  
}

这时候的用法:

Ageing ageingObj;    会调用先调用第二个构造函数,然后再调用第一个构造函数。其实就是传ture的参数
Ageing ageingObj(false);  调用第一个构造函数,传入false的参数

  在C++中,构造函数的委托(delegation)是一种允许一个构造函数调用同一类的另一个构造函数的语法。委托构造函数的语法形式是在构造函数的初始化列表中使用类名和参数列表来调用另一个构造函数。

 

2.访问私有类成员

class box{
    int height;
    int length;
    int width;

    int get_height(return height);
    int get_length(return length);
    int get_width(return width);

    box();
};

  通过定义类函数来访问私有类成员。这种函数一般放在类定义中,因为它们非常短,在默认情况下是内联函数。因此,获取数据成员值所涉及的系统开销就非常小。

  如果要把这些函数的定义放在类定义的外部,就应该把它们声明为inline(inline int get_height() {return height})。

 

3.友元

3.1 类的友元函数

  友元函数:不是类的一个成员,但可以访问类的所有成员(包括private),用关键字friend来声明。

/* 在.h文件中声明 */
class box{
public:
    box::box(int h, int l, int w : height(h), length(l), width(w))
    { }

    friend int boxSurface(const box &thebox);

private:
    int height;
    int length;
    int width;
};

/* 在.cpp中做函数定义 */
int main(void)
{
    box firstbox(1, 1, 1);

    boxSurface(firstbox);

    return 0;
}

/* 该函数是一个全局函数,只不过被声明为友元函数,其他用法与普通函数一样 */
int boxSurface(const box &thebox)
{
    return 2 * ((thebox.height * thebox.height) + \
    (thebox.length * thebox.length) + (thebox.width * thebox.width));
}

3.2 友元类

  把整个类声明为友元,友元类中的成员函数就可以不受限制访问原类的成员。

class box{
    /**/
    friend class Carton;
};

class Carton{
    /**/
};

  Carton是box的友元类,Carton类可以访问box的所有成员,但是box类不能访问Carton的成员。

  友元类的使用:链表。存储一个对象列表的List类和定义节点的Node类。List类需要在每个Node对象中设置一个指针,使该指针指向下一个节点,从而把Node对象组合在一起。把List类声明为定义节点类的友元,可以使List类的成员直接访问Node类的成员。

 4.this指针

  在执行任何类成员函数时,该函数都会自动包含一个隐藏的指针,称为this,该指针包含了调用该函数的对象的地址。

例如:

/* .cpp中实现 */
int box::volume()
{
    /* 编译器实现是:this->height * this->length * this->width */
    return height * length * width; 
}

使用例程:

/* 在.h文件中声明 */
class box{

public:
    box::box(int h, int l, int w : height(h), length(l), width(w))
    { }
    int volume();
    int comparevolume(box &otherbox);

private:
    int height;
    int length;
    int width;
};

/* .cpp中实现 */
int box::volume()
{
    /* 编译器实现是:this->height * this->length * this->width */
    return height * length * width; 
}

int box::comparevolume(box &otherbox)
{
    int val_1 = this->volume();
    int val_2 = otherbox.volume();
    return val_1 > val_2 ? 1 : 0;
}

/* 在.cpp中做函数定义 */
int main(void)
{
    box firstbox(1, 1, 1);
    box secondbox(2, 2, 2);

    secondbox.comparevolume(firstbox);

    return 0;
}

函数返回值this

  在上面的源码中添加:

/* 在.h文件中声明 */
    box* setlength(int lval); 
    box* setheight(int hval); 
    box* setwidth(int wval); 


/* .cpp中实现 */
box *box::setlength(int lval)
{
    if(lval > 0) length = lval;
    return this;
}

box *box::setheight(int hval)
{
    if(hval > 0) height = hval;
    return this;
}

box *box::setwidth(int wval)
{
    if(wval > 0) width = wval;
    return this;
}

int main(void)
{
  box abox(1, 1, 1);
  box *bbox = &abox;
  bbox->setlength(2)->setheight(2)->setwidth(2);
  return 0;
}

 5.const对象和const成员函数

  如果把上面的comparevolume函数的参数修改为comparevolume(const box &otherbox);

  这时候编译就会提示int val_2 = otherbox.volume();错误消息是不能转换this指针。

  这是因为把一个对象指定为const,就是告诉编译器不要修改它。在为常量对象otherbox调用函数volume函数时,编译器必须把otherbox的地址通过this指针传递给函数,但这样就不能保证函数不修改该对象。

  因此对于声明为const的对象,只能调用也声明为const的成员函数。

/* 在.h文件中声明 */
int volume() const;

/* .cpp中实现 */
int box::volume const()
{
    return height * length * width; 
}

 

6.mutable数据成员

  如果把对象声明为const,就只能调用const成员函数。不能修改对象的数据成员值,因为它们都是const。但是在一些情况下,即使对象声明为const,也需要修改类中一些选定的数据成员。

  因此可以把这些数据成员声明为mutable。

class SecureAccess{
public:
    bool isLocked() const;

private:
    mutable int time;
};

bool SecureAccess::isLocked() const{
    time = getCurrentTime();
    return lockStatus();
};

int main(void)
{
    const SecureAccess mainDoor;
    bool doorstate = mainDoor.isLocked();

    return 0;
}

  这样,通过const mainDoor可以获取状态值,并且可以记录时间戳。

7.类的静态成员

7.1 类的静态数据成员

   在把类的数据成员声明为static时,静态数据成员就只定义一次,而且即使类没有实例化对象,该静态数据成员依然存在。也就是无论实例化多少个对象,该静态数据成员只有一个,并且在这些对象中是共享的。

/* 在.h文件中声明 */
class box{
    static int objcount;
};

/* .cpp中实现 */
int box::objcount = 1;

  因为静态数据成员的初始化只能放在.cpp只初始化,并且初始化的时候必须加上类名,不然编译器会认为在定义一个objcount的变量。

7.2 类的静态成员函数

  静态成员函数就是在成员函数前面加static关键字。并且需要注意静态成员函数不能声明为const,因为静态成员函数与类的对象无关,它没有this指针,也只有一个定义,并且就算类没有实例化对象,该静态成员函数也是存在的,可以通过类名::静态成员函数来调用。

  因此类的静态成员函数需要操作对象,需要将对象作为参数传递。

class box{
    /**/
    static int sum(box thebox);
};

static int box::sum(box thebox)
{
    return thebox.height + thebox.width+thebox.length;
}

int main(void)
{
  box box1(1, 1, 1);
  box1.sum(box1);

}

 

  

  

 

posted @ 2023-02-27 17:03  一个不知道干嘛的小萌新  阅读(43)  评论(0编辑  收藏  举报