系统提供默认的拷贝构造器,一经定义不再提供。但系统提供的默认拷贝构造器是 等位拷贝,也就是通常意义上的浅拷贝。如果类中包含的数据元素全部在栈上,浅拷贝 也可以满足需求的。但如果堆上的数据,则会发生多次析构行为。

parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--source', type=str, default='data/images', help='source') # file/folder, 0 for webcam
parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
parser.add_argument('--max-det', type=int, default=1000, help='maximum number of detections per image')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='display results')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--update', action='store_true', help='update all models')
parser.add_argument('--project', default='#include <iostream>
#include <cstdlib>

using namespace std;

int strlen(const char s[]){
int len = 0;

while (s[len]){
len++;
}
return len; // 返回数组str中首个值为null的元素的下标值
}

char* strcpy(char *p, const char *s){
char *t = p;

while (*p++ = *s++){

}

return t;
}


class Teacher{
public:
//有参数的构造函数
Teacher(int id, const char *name){
cout << "调用了Teacher 的构造函数" << endl;
//是给id 赋值
m_id = id;

//给姓名赋值
int len = strlen(name);
m_name = (char*)malloc(len + 1);
strcpy(m_name, name);
}

//显示写一个拷贝构造函数
//通过显示拷贝构造函数提供了深拷贝的动作
Teacher(const Teacher &another){
m_id = another.m_id; //给id赋值

int len = strlen(another.m_name);
m_name = (char*)malloc(len + 1);

strcpy(m_name, another.m_name);
}
~Teacher() {
//在构造函数中, 已经开辟了内存 所以为了防止泄露
//在析构函数中,在对象销毁之前,把m_name的内存释放掉
if (m_name != NULL) {
free(m_name);
m_name = NULL;
cout << "释放掉了m_name" << endl;
}
}
private:
int m_id;
char *m_name;
};

int main(void){
Teacher t1(1, "vvcat");

//如果不提供一个显示的拷贝构造函数, 通过系统自带的默认拷贝构造函数
Teacher t2(t1); //会调用t2的拷贝构造函数,将t1的值拷贝给t2
}runs/detect', help='save results to project/name')
parser.add_argument('--name', default='exp', help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
opt = parser.parse_args()

注:

  1. 当类中声明的成员变量有char *时,在变量调用有参函数或无参函数进行初始化的时候,需要对成员变量开辟一个存储该变量的空间,如果在后续的操作中,有调用​​拷贝构造函数​​​需要对变量进行​​深拷贝的动作​​​,为拷贝后的变量开辟一个新的空间,使拷贝变量和被拷贝变量的空间互不影响。
    如果在​​​拷贝构造函数​​​没有对变量进行​​深拷贝​​​的动作而使用了​​浅拷贝​​​的动作,程序会报错或者会因为 char * 变量因为没有得到释放,导致程序崩溃。
    以下是,错误举例:
Teacher(const Teacher &another){
m_id = another.m_id; //给id赋值

m_name = another.m_name; // 这里会使程序报错
}
  1. Teacher(int id, const char *name) 中,在一些编译器中省略​​const​​会出现报错,而在一些编译器中会出现 警告的提示,所以一般在编写代码中尽量不要省略。
  2. ​深拷贝​​可以防止重复释放同一块内存和内存的泄漏。