返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++详细讲解对象的构造
  • 743
分享到

C++详细讲解对象的构造

2024-04-02 19:04:59 743人浏览 安东尼
摘要

目录一、对象的构造(上)1.1 对象的初始值1.2 对象的初始化1.3 小结二、对象的构造(中)2.1 构造函数2.2小实例2.3 小结三、对象的构造(下)3.1 特殊的构造函数3.

一、对象的构造(上)

1.1 对象的初始值

问题:对象中成员变量的初始值是多少?

下面的类定义中成员变量 i 和 j 的初始值为多少?

下面看一段成员变量初始值的代码:

#include<stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI() {return i;}
        int getJ() {return j;}
};
 
Test gt;
 
int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());   
    
    delete pt;
    
    return 0;
}

下面为输出结果:

对象t1 所占用的存储空间在栈上面,而且成员变量 i 和 j 也没有明确的初始值,所以初始值就不定。对象 gt 所占用的存储空间在全局数据区,所以初始值统一为 0。

Test* pt = new Test;意味着在堆空间中生成一个 Test 对象,虽然 pt->i 和 pt->j 均为 0,这只是巧合罢了,因为在堆上创建对象时,成员变量初始为随机值。

注:类得到的其实是数据类型,所以说通过这种数据类型在全局数据区、栈和堆上面都能够生成对象。

1.2 对象的初始化

从程序设计的角度,对象只是变量,因此:

  • 在栈上创建对象时,成员变量初始为随机值
  • 在堆上创建对象时,成员变量初始为随机值
  • 在静态存储区创建对象时,成员变量初始为 0 值

生活中的对象都是在初始化后上市的

初始状态(出厂设置)是对象普遍存在的一个状态

—股而言,对象都需要—个确定的初始状态

解决方案

  • 在类中提供一个 public 的 initialize 函数
  • 对象创建后立即调用 initialize 函数进行初始化

如下:

下面看一段初始化函数的代码:

#include<stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI() {return i;}
        int getJ() {return j;}
        void initialize()
        {
            i = 1;
            j = 2;
        }
};
 
Test gt;
 
int main()
{
    gt.initialize();
    
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    
    t1.initialize();
    
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    pt->initialize();
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());   
    
    delete pt;
    
    return 0;
}

下面为输出结果:

存在的问题

  • initialize 只是一个普通函数,必须显示调用
  • 如果未调用 initialize 函数,运行结果是不确定的

下面为解决办法:

c++中可以定义与类名相同的特殊成员函数

这种特殊的成员函数叫做构造函数

  • 构造没有任何返回类型的声明
  • 构造函数在对象定义时自动被调用

下面来体验一下构造函数:

#include<stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI() {return i;}
        int getJ() {return j;}
        Test()
        {
            printf("Test() Begin\n");
        
            i = 1;
            j = 2;
        
            printf("Test() End\n");
        }
};
 
Test gt;
 
int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());   
    
    delete pt;
    
    return 0;
}

下面为输出结果:

可以看到,Test() Begin 和 Test() End 出现了三次,也就是说,Test() 这个构造函数被调用了三次,这是因为创建了三个对象。

1.3 小结

  • 每个对象在使用之前都应该初始化
  • 类的构造函数用于对象的初始化
  • 构造函数与类同名并且没有返回值
  • 构造函数在对象定义时自动被调用

二、对象的构造(中)

2.1 构造函数

带有参数的构造函数

  • 构造函数可以根据需要定义参数
  • 一个类中可以存在多个重载的构造函数
  • 构造函数的重载遵循 C++ 重载的规则

如下:

友情提醒

对象定义和对象声明不同

  • 对象定义--申请对象的空间并调用构造函数
  • 对象声明--告诉编译器存在这样一个对象

如下:

构造函数的自动调用

如下:

下面看一段带参数的构造函数的代码:

#include <stdio.h>
 
class Test
{
    public:
        Test() 
        { 
            printf("Test()\n");
        }
        Test(int v) 
        { 
            printf("Test(int v), v = %d\n", v);
        }
};
 
int main()
{
    Test t;      // 调用 Test()
    Test t1(1);  // 调用 Test(int v)
    Test t2 = 2; // 调用 Test(int v)
    
    return 0;
}

下面为输出结果,和预想中的一致。

这里需要明确一个问题,int i = 1;与 int i; i = 1;的不同。前者是初始化,后者是先定义,再赋值。后者由于定义 i 时没有初始化,所以 i 的值时随机的。C语言中这两者差别很小,但是在 C++ 中两者差异很大。差别在于在 C++ 中初始化会调用构造函数。下面看一个例子,在上述代码的基础上加一行代码 t = t2;

#include <stdio.h>
 
class Test
{
    public:
        Test() 
        { 
            printf("Test()\n");
        }
        Test(int v) 
        { 
            printf("Test(int v), v = %d\n", v);
        }
};
 
int main()
{
    Test t;      // 调用 Test()
    Test t1(1);  // 调用 Test(int v)
    Test t2 = 2; // 调用 Test(int v)
    
    t = t2;
    
    return 0;
}

下面为输出结果,可以看到与上面的代码输出结果一模一样。这就因为 C++ 中初始化和赋值不同,初始化会调用构造函数,赋值的时候则不用。

下面再看一个例子:

#include <stdio.h>
 
class Test
{
    public:
        Test() 
        { 
            printf("Test()\n");
        }
        Test(int v) 
        { 
            printf("Test(int v), v = %d\n", v);
        }
};
 
int main()
{
    Test t;      // 调用 Test()
    Test t1(1);  // 调用 Test(int v)
    Test t2 = 2; // 调用 Test(int v)
    
    int i(100);
    
    printf("i = %d\n", i);
    
    return 0;
}

下面为输出结果:

构造函数的调用

  • 一般情况下,构造函数在对象定义时被自动调用
  • —些特殊情况下,需要手工调用构造函数

下面看一段构造函数手动调用的代码:

#include <stdio.h>
 
class Test
{
    private:
        int m_value;
    public:
        Test() 
        { 
            printf("Test()\n");
        
            m_value = 0;
        }
        
        Test(int v) 
        { 
            printf("Test(int v), v = %d\n", v);
        
            m_value = v;
        }
        
        int getValue()
        {
            return m_value;
        }
};
 
int main()
{
    Test ta[3] = {Test(), Test(1), Test(2)};      
    
    for (int i = 0; i < 3; i++)
    {
        printf("ta[%d].getValue() = %d\n", i, ta[i].getValue());
    }
    
    Test t = Test(100);
    
    printf("t.getValue() = %d\n", t.getValue());
    
    return 0;
}

下面为输出结果,可以看到,Test(1)、Test(2) 和 Test(100) 均为手动调用构造函数。

2.2小实例

需求:开发一个数组类解决原生数组的安全性问题

  • 提供函数获取数组长度
  • 提供函数获取数组元素
  • 提供函数设置数组元素

IntArray.h:

#ifndef _INTARRAY_H_
 
#define _INTARRAY_H_

class IntArray
 
{
    private:
        int m_length;
 
        int* m_pointer;
    public:
        IntArray(int len);
 
        int length();
 
        bool get(int index, int& value);
 
        bool set(int index ,int value);
 
        void free();
};
#endif

IntArray.cpp:

#include "IntArray.h"
 
 
 
IntArray::IntArray(int len)
 
{
 
    m_pointer = new int[len];
 
    
 
    for (int i = 0; i < len; i++)
 
    {
 
        m_pointer[i] = 0;
 
    }
 
    
 
    m_length = len;
 
}
 
 
 
int IntArray::length()
 
{
 
    return m_length;
 
}
 
 
 
bool IntArray::get(int index, int& value)
 
{
 
    bool ret = (0 <= index) && (index < length());
 
    
 
    if( ret )
 
    {
 
        value = m_pointer[index];
 
    }
 
    
 
    return ret;
 
}
 
 
 
bool IntArray::set(int index, int value)
 
{
 
    bool ret = (0 <= index) && (index < length());
 
    
 
    if( ret )
 
    {
 
        m_pointer[index] = value;
 
    }
 
    
 
    return ret;
 
}
 
 
 
void IntArray::free()
 
{
 
    delete[]m_pointer;
 
}

main.cpp:

#include <stdio.h>
 
#include "IntArray.h"
 
 
 
int main()
 
{
 
    IntArray a(5);    
 
    
 
    for (int i = 0; i < a.length(); i++)
 
    {
 
        a.set(i, i + 1);
 
    }
 
    
 
    for (int i = 0; i < a .length(); i++)
 
    {
 
        int value = 0;
 
        
 
        if( a.get(i, value) )
 
        {
 
            printf("a[%d] = %d\n", i, value);
 
        }
 
    }
 
    
 
    a.free();
 
    
 
    return 0;
 
}

下面为输出结果:

这样写出来的数组很安全,没有数组越界问题。

2.3 小结

  • 构造函数可以根据需要定义参数
  • 构造函数之间可以存在重载关系
  • 构造函数遵循 C++ 中重载函数的规则
  • 对象定义时会触发构造函数的调用
  • 在一些情况下可以手动调用构造函数

三、对象的构造(下)

3.1 特殊的构造函数

两个特殊的构造函数

无参构造函数

  • 没有参数的构造函数
  • 当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空

拷贝构造函数

  • 参数为 const class_name& 的构造函数
  • 当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制

下面看一段无参数构造函数的代码(代码3-1):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
};
 
int main()
{
    Test t;
    
    return 0;
}

可以看到,编译通过:

创建一个类的对象必须要调用构造函数,为什么能够编译通过呢?这是因为编译器在发现我们没有定义构造函数时,会默认提供一个无参构造函数,等效如(代码3-2):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
        Test()
        {
        }
};
 
int main()
{
    Test t;
    
    return 0;
}

小贴士:所以说,class T { }; 里面不是什么都没有,里面至少有一个无参构造函数。

下面再来看一段代码(代码3-3):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
};
 
int main()
{
    Test t1;
    Test t2 = t1;
    
    printf("t1.i = %d, t1.j = %d\n", t1.getI(), t1.getJ());
    printf("t2.i = %d, t2.j = %d\n", t2.getI(), t2.getJ());
    
    return 0;
}

下面为输出结果:

这里的 i 和 j 打印出来的都是随机值,这是因为类里面没有手工编写的构造函数,所以 t1 和 t2 所采用的就是编译器提供的默认无参构造函数构造的,编译器提供的无参构造函数为空,所以 i 和 j 的值就是随机的。

上述代码就相当于(代码3-4):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
        Test(const Test& t)
        {
            i = t.i;
            j = t.j;        
        }
};
 
int main()
{
    Test t1;
    Test t2 = t1;
    
    printf("t1.i = %d, t1.j = %d\n", t1.getI(), t1.getJ());
    printf("t2.i = %d, t2.j = %d\n", t2.getI(), t2.getJ());
    
    return 0;
}

但是编译的时候会报错:

这是因为在类里面没有编写任何构造函数时,编译器才提供默认的无参构造函数。这里手工编写了一个拷贝构造函数,编译器就不会提供默认的无参构造函数,需要自己把无参构造函数加上。

如下,自己加上无参构造函数(代码3-5):

#include <stdio.h>
class Test
{
    private:
        int i;
        int j;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
        Test(const Test& t)
        {
            i = t.i;
            j = t.j;        
        }
        Test()
        {
        }
};
 
int main()
{
    Test t1;
    Test t2 = t1;
    
    printf("t1.i = %d, t1.j = %d\n", t1.getI(), t1.getJ());
    printf("t2.i = %d, t2.j = %d\n", t2.getI(), t2.getJ());
    
    return 0;
}

这样就能编译通过了,而且效果跟代码3-3的相同:

3.2 拷贝构造函数

拷贝构造函数的意义

兼容C语言的初始化方式

初始化行为能够符合预期的逻辑

浅拷贝

  • 拷贝后对象的物理状态相同(物理状态指的是对象占据的内存当中每个字节是否相等,如代码3-6)

深拷贝

  • 拷贝后对象的逻辑状态相同(逻辑状态指的是指针所指向的内存空间的值是否相同,如代码3-9)

注:编译器提供的拷贝构造函数只进行浅拷贝!

下面看一段代码(代码3-6):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
        int* p;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
        int* getP()
        {
            return p;
        }
        Test(int v)
        {
            i = 1;
            j = 2;
            p = new int;
        
            *p = v;
        }
 
};
 
int main()
{
    Test t1(3);
    Test t2 = t1;
    
    printf("t1.i = %d, t1.j = %d, t1.p = %p\n", t1.getI(), t1.getJ(), t1.getP());
    printf("t2.i = %d, t2.j = %d, t2.p = %p\n", t2.getI(), t2.getJ(), t2.getP());
    
    return 0;
}

下面为输出结果:

这段程序的第一个问题就是 t1 和 t2 的 p 指针都指向同一个堆空间中的地址,第二个问题就是申请了内存并没有释放,会造成内存泄漏。

下面加上释放内存的代码(代码3-7):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
        int* p;
    public:
        int getI()
        {
            return i;
        }
        int getJ()
        {
            return j;
        }
        int* getP()
        {
            return p;
        }
        Test(int v)
        {
            i = 1;
            j = 2;
            p = new int;
        
            *p = v;
        }
        void free()
        {
            delete p;
        }
 
};
 
int main()
{
    Test t1(3);
    Test t2 = t1;
    
    printf("t1.i = %d, t1.j = %d, t1.p = %p\n", t1.getI(), t1.getJ(), t1.getP());
    printf("t2.i = %d, t2.j = %d, t2.p = %p\n", t2.getI(), t2.getJ(), t2.getP());
    
    t1.free();
    t2.free();
    
    return 0;
}

下面为输出结果,编译能通过,但是运行时发生了错误,释放了两次堆空间的内存:

下面为解决方法(代码3-8):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
        int* p;
    public:
        int getI()
        {
            return i;
        }
        
        int getJ()
        {
            return j;
        }
        
        int* getP()
        {
            return p;
        }
        
        Test(const Test& t)
        {
            i = t.i;
            j = t.j;
            p = new int;
            
            *p = *t.p;
        }
        
        Test(int v)
        {
            i = 1;
            j = 2;
            p = new int;
        
            *p = v;
        }
        
        void free()
        {
            delete p;
        }
 
};
 
int main()
{
    Test t1(3);
    Test t2(t1);
    
    printf("t1.i = %d, t1.j = %d, t1.p = %p\n", t1.getI(), t1.getJ(), t1.getP());
    printf("t2.i = %d, t2.j = %d, t2.p = %p\n", t2.getI(), t2.getJ(), t2.getP());
    
    t1.free();
    t2.free();
    
    return 0;
}

下面为输出结果,可以到 t1 和 t2 的 p 指针分别指向不同的堆空间地址:

如果我们看一下逻辑状态,也就是 *t1.p 和 *t2.p 的值,代码如下(代码3-9):

#include <stdio.h>
 
class Test
{
    private:
        int i;
        int j;
        int* p;
    public:
        int getI()
        {
            return i;
        }
        
        int getJ()
        {
            return j;
        }
        
        int* getP()
        {
            return p;
        }
        
        Test(const Test& t)
        {
            i = t.i;
            j = t.j;
            p = new int;
            
            *p = *t.p;
        }
        
        Test(int v)
        {
            i = 1;
            j = 2;
            p = new int;
        
            *p = v;
        }
        
        void free()
        {
            delete p;
        }
 
};
 
int main()
{
    Test t1(3);
    Test t2(t1);
    
    printf("t1.i = %d, t1.j = %d, t1.p = %p\n", t1.getI(), t1.getJ(), t1.getP());
    printf("t2.i = %d, t2.j = %d, t2.p = %p\n", t2.getI(), t2.getJ(), t2.getP());
    
    t1.free();
    t2.free();
    
    return 0;
}

下面为输出结果,可以看到 *t1.p 和 *t2.p 的值相同,也就是说逻辑状态相同,这就叫做深拷贝。

什么时候需要进行深拷贝?

对象中有成员指代了系统中的资源

  • 成员指向了动态内存空间
  • 成员打开了外存中的文件
  • 成员使用了系统中的网络端口
  • ......

问题分析

下面就是浅拷贝:

一般性原则

自定义拷贝构造函数,必然需要实现深拷贝!!!

下面看一个使用深拷贝,对前面数组的代码进行改造。

IntArray.h:

#ifndef _INTARRAY_H_
 
#define _INTARRAY_H_
class IntArray
 
{
 
    private:
 
        int m_length;
 
        int* m_pointer;
 
    public:
 
        IntArray(int len);
 
        IntArray(const IntArray& obj);
 
        int length();
 
        bool get(int index, int& value);
 
        bool set(int index ,int value);
 
        void free();
 
};
#endif

IntArray.cpp:

#include "IntArray.h"
 
 
 
IntArray::IntArray(int len)
 
{
 
    m_pointer = new int[len];
 
    
 
    for (int i = 0; i < len; i++)
 
    {
 
        m_pointer[i] = 0;
 
    }
 
    
 
    m_length = len;
 
}
 
 
 
IntArray::IntArray(const IntArray& obj)
 
{
 
    m_length = obj.m_length;
 
    
 
    m_pointer = new int[obj.m_length];
 
    
 
    for (int i = 0; i < obj.m_length; i++)
 
    {
 
        m_pointer[i] = obj.m_pointer[i];
 
    }
 
}
 
 
 
int IntArray::length()
 
{
 
    return m_length;
 
}
 
 
 
bool IntArray::get(int index, int& value)
 
{
 
    bool ret = (0 <= index) && (index < length());
 
    
 
    if( ret )
 
    {
 
        value = m_pointer[index];
 
    }
 
    
 
    return ret;
 
}
 
 
 
bool IntArray::set(int index, int value)
 
{
 
    bool ret = (0 <= index) && (index < length());
 
    
 
    if( ret )
 
    {
 
        m_pointer[index] = value;
 
    }
 
    
 
    return ret;
 
}
 
 
 
void IntArray::free()
 
{
 
    delete[]m_pointer;
 
}

main.cpp:

#include <stdio.h>
 
#include "IntArray.h"
 
 
 
int main()
 
{
 
    IntArray a(5);    
 
    
 
    for (int i = 0; i < a.length(); i++)
 
    {
 
        a.set(i, i + 1);
 
    }
 
    
 
    for (int i = 0; i < a.length(); i++)
 
    {
 
        int value = 0;
 
        
 
        if( a.get(i, value) )
 
        {
 
            printf("a[%d] = %d\n", i, value);
 
        }
 
    }
 
    
 
    IntArray b = a;
 
    
 
    for (int i = 0; i < b.length(); i++)
 
    {
 
        int value = 0;
 
        
 
        if( b.get(i, value) )
 
        {
 
            printf("b[%d] = %d\n", i, value);
 
        }
 
    }
 
    
 
    a.free();
 
    b.free();
 
    
 
    return 0;
 
}

下面为输出结果:

可以看到 b 数组里面的元素与 a 数组里面的元素相同,这就是深拷贝构造函数的结果。

3.3 小结

C++ 编译器会默认提供构造函数

无参构造函数用于定义对象的默认初始状态

拷贝构造函数在创建对象时拷贝对象的状态

对象的拷贝有浅拷贝和深拷贝两种方式

  • 浅拷贝使得对象的物理状态相同
  • 深拷贝使得对象的逻辑状态相同

到此这篇关于C++详细讲解对象的构造的文章就介绍到这了,更多相关C++ 对象的构造内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++详细讲解对象的构造

本文链接: https://lsjlt.com/news/146586.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++详细讲解对象的构造
    目录一、对象的构造(上)1.1 对象的初始值1.2 对象的初始化1.3 小结二、对象的构造(中)2.1 构造函数2.2小实例2.3 小结三、对象的构造(下)3.1 特殊的构造函数3....
    99+
    2024-04-02
  • C++详细讲解对象的构造顺序
    目录一、局部对象的构造顺序二、堆对象的构造顺序三、全局对象的构造顺序命令行四、小结一、局部对象的构造顺序 对于局部对象 当程序执行流到达对象的定义语句时进行构造 下面看一个局部对象的...
    99+
    2024-04-02
  • Java 超详细讲解对象的构造及初始化
    目录如何初始化对象构造方法特性默认初始化就地初始化如何初始化对象 我们知道再Java方法内部定义一个局部变量的时候,必须要初始化,否则就会编译失败 要让这串代码通过编译,很简单,只...
    99+
    2024-04-02
  • C++超详细讲解构造函数
    目录类的6个默认成员函数构造函数特性编译器生成的默认构造函数成员变量的命名风格类的6个默认成员函数 如果我们写了一个类,这个类我们只写了成员变量没有定义成员函数,那么这个类中就没有函...
    99+
    2024-04-02
  • C++OOP对象和类的详细讲解
    目录C++OOP对象和类1.预备知识2.抽象和类2.1 数据抽象2.2 类2.3 接口3.C++中的类和对象3.1 C++类的定义3.2 C++对象的定义3.3 C++访问数据成员3...
    99+
    2024-04-02
  • C++超详细讲解函数对象
    目录一、客户需求二、存在的问题三、解决方案四、函数对象五、小结一、客户需求 编写一个函数 函数可以获得斐波那契数列每项的值每调用一次返回一个值函数可根据需要重复使用 下面来看第一个...
    99+
    2024-04-02
  • C++超详细讲解拷贝构造函数
    目录构造函数特征编译器生成的拷贝构造拷贝构造的初始化列表显式定义拷贝构造的误区结论构造函数 只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对...
    99+
    2024-04-02
  • c++详细讲解构造函数的拷贝流程
    #include <iostream> #include <string> using namespace std; void func(string str...
    99+
    2024-04-02
  • C++面向对象中构造函数使用详解
    目录构造函数作用构造函数特征构造函数种类默认构造函数编译器合成的默认构造函数手动定义的默认构造函数自定义带参数的构造函数拷贝构造函数合成拷贝构造函数自定义拷贝构造函数拷贝构造函数的调...
    99+
    2022-11-13
    C++构造函数的作用 C++构造函数的写法
  • Vue对象的深层劫持详细讲解
    目录一,前言二,对象属性的深层观测问题1,抛出问题2,测试问题3,查看结果三,对象属性深层观测的实现1,实现思路2,代码逻辑四,data 相关优化五,结尾一,前言 上篇,主要介绍了在...
    99+
    2023-01-06
    Vue对象深层劫持 Vue深层劫持 Vue对象劫持
  • C++超详细讲解构造函数与析构函数的用法及实现
    目录写在前面构造函数和析构函数语法作用代码实现两大分类方式三种调用方式括号法显示法隐式转换法正确调用拷贝构造函数正常调用值传递的方式给函数参数传值值传递方式返回局部对象构造函数的调用...
    99+
    2024-04-02
  • C++超详细讲解析构函数
    目录特性析构函数处理自定义类型编译器生成的默认析构函数特性 析构函数是特殊的成员函数 特征如下: 析构函数名是~类名;无参数无返回值;一个类有且只有一个析构函数;对象声明周期结束,编...
    99+
    2024-04-02
  • C++继承中的对象构造与析构和赋值重载详解
    目录一、构造/析构顺序及继承性二、拷贝构造的继承性三、赋值重载不具有继承性总结一、构造/析构顺序及继承性 class A { private: int _a; public: A...
    99+
    2024-04-02
  • C++对象的构造实例分析
    这篇“C++对象的构造实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++对象的构造实例分析”文章吧。一、对象的构造...
    99+
    2023-06-30
  • JavaScript面向对象编程详细讲解
    这篇文章主要介绍“JavaScript面向对象编程详细讲解”,在日常操作中,相信很多人在JavaScript面向对象编程详细讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • C++类与对象及构造函数析构函数基础详解
    目录C++类与对象类的定义对象的创建构造函数和析构函数访问修饰符继承多态成员变量与成员方法总结C++类与对象 C++是一门面向对象的编程语言。在C++中,我们可以利用类来创建对象,...
    99+
    2023-05-16
    C++类对象函数 c++ 构造析构函数
  • 讲解Java中如何构造内部类对象以及访问对象
    通过反射构造内部类对象 首先在 javalang 包下写一个包含内部类的类: package javalang; public class Outer { public s...
    99+
    2022-05-28
    Java
  • C语言结构体(struct)的详细讲解
    目录引言1. 动态内存管理2. 结构体2.1 定义语法2.2 定义示例2.3 初始化2.4 结构体赋值2.5 结构体数组2.6 结构体指针赋值3. 学生管理系统附:结构体变量的存储原...
    99+
    2024-04-02
  • Golang创建构造函数的方法超详细讲解
    目录组合字面量自定义构造函数从构造函数返回错误interface构造函数最佳实践基本构造函数主包类型多个构造函数组合字面量 组合字面量是最直接方式初始化Go对象,假设定义了Book类...
    99+
    2023-01-28
    Go创建构造函数 Go构造函数
  • C语言结构体超详细讲解
    目录前言1、结构体的声明1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的定义和初始化2、结构体成员的访问2.1 点操作符访问2.2 ->操作符...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作