【转】C++中的构造函数设计

详解C++中的构造函数 C++编译器默认生成的构造函数设计得不好,它没有对内置类型和自定义类型统一处理,它不会处理内置类型成员变量,只处理自定义类型成员变量说白了就是,对象在定义使会调用构造函数,对于内置类型来说 有没有默认构造函数都可以,但是对于自定义类型来说,如果没有默认构造函数就会报错,不管这个默认构造函数是你自己定义的还是编译器自动生成的 如果你自己写了那么编译器就不会生成了,但是如果你写的构造函数一定需要参数才可以调用(也就是说他不是默认构造函数),那么编译器就会报错 而所谓的。 阅读详情

 

C++中的构造函数设计

 

     在C++中,构造函数是一个在构件对象的时候调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。比如说,限定构造函数名称与类的名称相同的条件。这些特性在构造C++编译器的时候是值得引起注意的。还有,在今后C++的标准修订或者制定其他面向对象的设计语言时候应当避免这些特性。这里也提出了一些解决的方案。

     C++中,任何类都有一个(至少有一个)构造函数,甚至在没有构造函数被声明的时候亦是如此。在对象被声明的时候,或者被动态生成的时候,这些构造函数就会被调用。构造函数做了许多不可见的工作,即使构造函数中没有任何代码,这些工作包括对对象的内存分配和通过赋值的方式对成员进行初始化。构造函数的名称必须与类的名称相同,但是可以有许多不同的重载版本来提供,通过参数类型来区分构造函数的版本。构造函数可以显式的通过用户代码来调用,或者当代码不存在是通过编译程序来隐式插入。当然,显式地通过代码调用是推荐的方法,因为隐式调用的效果可能不是我们所预料的,特别是在处理动态内存分配方面。代码通过参数来调用唯一的构造函数。构造函数没有返回值,尽管在函数体中可以又返回语句。每个构造函数可以以不同的方式来实例化一个对象,因为每个类都有构造函数,至少也是缺省构造函数,所以每个对象在使用之前都相应的使用构造函数。构造函数的调用如图1所示。

    图1. The activities involved in the execution of a constructor

     因为构造函数是一种函数,所以他的可见性无非是三种public、private、protected。通常,构造函数都被声明为 public型。如果构造函数被声明为private或protected,就限制了对象的实例化。这在阻止类被其他人实例化的方面很有效。构造函数中可以有任何C++的语句,比如,一条打印语句,可以被加入到构造函数中来表明调用的位置。

    构造函数的类型

      C++中构造函数有许多种类型,最常用的式缺省构造函数和拷贝构造函数,也存在一些不常用的构造函数。下面介绍了四种不同的构造函数。

    1、缺省构造函数

     缺省构造函数是没有参数的函数。另外,缺省构造函数也可以在参数列表中以参数缺省值的方式声明。缺省构造函数的作用是把对象初始化为缺省的状态。如果在类中没有显式定义构造函数,那么编译器会自动的隐式创建一个,这个隐式创建的构造函数和一个空的构造函数很相像。他除了产生对象的实例以外什么工作都不做。在许多情况下,缺省构造函数都会被自动的调用,例如在一个对象被声明的时候,就会引起缺省构造函数的调用。

    2、拷贝构造函数

     拷贝构造函数,经常被称作X(X&),是一种特殊的构造函数,他由编译器调用来完成一些基于同一类的其他对象的构件及初始化。它的唯一的一个参数(对象的引用)是不可变的(因为是const型的)。这个函数经常用在函数调用期间于用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。

    在C++中,下面三种对象需要拷贝的情况。因此,拷贝构造函数将会被调用。

    1). 一个对象以值传递的方式传入函数体

    2). 一个对象以值传递的方式从函数返回

    3). 一个对象需要通过另外一个对象进行初始化

     以上的情况需要拷贝构造函数的调用。如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作赋共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。

     拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环。

     除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。换句话说,你从函数返回得到的只是对象的一份拷贝。但是同样的,拷贝构造函数被正确的调用了,你不必担心。

     如果在类中没有显式的声明一个拷贝构造函数,那么,编译器会私下里为你制定一个函数来进行对象之间的位拷贝(bitwise copy)。这个隐含的拷贝构造函数简单的关联了所有的类成员。许多作者都会提及这个默认的拷贝构造函数。注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对于成员的关联方式。显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数除非另外一个构造函数在类初始化或者在构造列表的时候被调用。

     拷贝构造函数是程序更加有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统提供的帮助你申请内存默认拷贝构造函数。事实上,默认拷贝构造函数可以应付许多情况。

    3、用户定义的构造函数

     用户定义的构造函数允许对象在被定义的时候同时被初始化。这种构造函数可以有任何类型的参数。一个用户定义的和其它类型的构造函数在类mystring 中得以体现:

class mystring

{......

public: mystring(); // Default constructor

mystring (mystring &src)

// Copy constructor

mystring (char * scr);

// Coercion constructor

mystring ( char scr[ ], size_t len);

// User-Defined constructor

};

    4、强制构造函数

     C++中,可以声明一个只有一个参数的构造函数来进行类型转换。强制构造函数定一个从参数类型进行的一个类型转换(隐式的或显式的)。换句话说,编译器可以用任何参数的实例来调用构造函数。这样做的目的是建立一个临时实例来替换一个参数类型的实例。注意标准新近加入C++的关键字 explicit 是用来禁止隐式的类型转换。然而,这一特性还没能被所有的编译器支持。下面是一个强制构造函数的例子:

class A

{
public :
    A(int ){ }
};

void f(A) { }

void g()

{
    A My_Object= 17;
    A a2 = A(57);
    A a3(64);
    My_Object = 67;
    f(77);
}

     像A My_Object= 17;这种声明意味着A(int)构造函数被调用来从整型变量生成一个对象。这样的构造函数就是强制构造函数。

     普遍特性

     下面是一些C++构造函数的不合理设计,当然,可能还有其他一些不合理之处。但是,大多数情况下,我们还是要和这些特性打交道,我们要逐一说明。

    1、构造函数可以为内联,但不要这样做

     一般来讲,大多数成员函数都可以在前面加入"inline"关键字而成为内联函数,构造函数也不例外,但是别这么做!一个被定义为内联的构造函数如下:

class x

{..........

public : x (int );

:

:

};

inline x::x(int )

{...}

     在上面的代码中,函数并不是作为一个单独的实体而是被插入到程序代码中。这对于只有一两条语句的函数来说会提到效率,因为这里没有调用函数的开销。

     用内联的构造函数的危险性可以在定义一个静态内联构造函数中体现。在这种情况下,静态的构造函数应当是只被调用一次。然而,如果头文件中含有静态内联构造函数,并被其他单元包括的话,函数就会产生多次拷贝。这样,在程序启动时就会调用所有的函数拷贝,而不是程序应当调用的一份拷贝。这其中的根本原因是静态函数是在以函数伪装下的真实对象。

     应该牢记的一件事是内联是建议而不是强制,编译器产生内联代码。这意味着内联是与实现有关的编译器的不同可能带来很多差异。另一方面,内联函数中可能包括比代码更多的东西。构造函数被声明为内联,所有包含对象的构造函数和基类的构造函数都需要被调用。这些调用是隐含在构造函数中的。这可能会创建很大的内联函数段,所以,不推荐使用内联的构造函数。

    2、构造函数没有任何返回类型

     对一个构造函数指定一个返回类型是一个错误,因为这样会引入构造函数的地址。这意味着将无法处理出错。这样,一个构造函数是否成功的创建一个对象将不可以通过返回之来确定。事实上,尽管C++的构造函数不可以返回,也有一个方法来确定是否内存分配成功地进行。这种方法是内建在语言内部来处理紧急情况的机制。一个预定好的函数指针 new-handler,它可以被设置为用户定制的对付new操作符失败的函数,这个函数可以进行任何的动作,包括设置错误标志、重新申请内存、退出程序或者抛出异常。你可以安心的使用系统内建的new-handler。最好的使构造函数发出出错信号的方法,就是抛出异常。在构造函数中抛出异常将清除错误之前创建的任何对象及分配的内存。

     如果构造函数失败而使用异常处理的话,那么,在另一个函数中进行初始化可能是一个更好的主意。这样,程序员就可以安全的构件对象并得到一个合理的指针。然后,初始化函数被调用。如果初始化失败的话,对象直接被清除。

    3、构造函数不可以被声明为static

     C++中,每一个类的对象都拥有类数据成员的一份拷贝。但是,静态成员则没有这样而是所有的对象共享一个静态成员。静态函数是作用于类的操作,而不是作用在对象上。可以用类名和作用控制操作符来调用一个静态函数。这其中的一个例外就是构造函数,因为它违反了面向对象的概念。

     关于这些的一个相似的现象是静态对象,静态对象的初始化是在程序的一开始阶段就进行的(在main()函数之前)。下面的代码解释了这种情况。

MyClass static_object(88, 91);

void bar()

{
    if (static_object.count( ) > 14) {
        ...
    }
}

     在这个例子中,静态变量在一开始的时候就被初始化。通常这些对象由两部分构成。第一部分是数据段,静态变量被读取到全局的数据段中。第二部分是静态的初始化函数,在main()函数之前被调用。我们发现,一些编译器没有对初始化的可靠性进行检查。所以你得到的是未经初始化的对象。解决的方案是,写一个封装函数,将所有的静态对象的引用都置于这个函数的调用中,上面的例子应当这样改写。

static MyClass* static_object = 0;

MyClass*

getStaticObject()

{
    if (!static_object)
        static_object =
        new MyClass(87, 92);
    return static_object;
}

void bar()

{
    if (getStaticObject()->count() > 15)
    {
        ...
    }
}

    4、构造函数不能成为虚函数

     虚构造函数意味着程序员在运行之前可以在不知道对象的准确类型的情况下创建对象。虚构造函数在C++中是不可能实现的。最通常遇到这种情况的地方是在对象上实现I/O的时候。即使足够的类的内部信息在文件中给出,也必须找到一种方法实例化相应的类。然而,有经验的C++程序员会有其他的办法来模拟虚构造函数。

     模拟虚函数需要在创建对象的时候指定调用的构造函数,标准的方法是调用虚的成员函数。很不幸,C++在语法上不支持虚构造函数。为了绕过这个限制,一些现成的方法可以在运行时刻确定构件的对象。这些等同于虚构造函数,但是这是C++中根本不存在的东西。

     第一个方法是用switch或者if-else选择语句来手动实现选择。在下面的例子中,选择是基于标准库的type_info构造,通过打开运行时刻类型信息支持。但是你也可以通过虚函数来实现RTTI

class Base

{
public:
    virtual const char* get_type_id() const;
    staticBase* make_object
        (const char* type_name);
};

const char* Base::get_type_id() const

{
    return typeid(*this).raw_name();
}

class Child1: public Base

{
};

class Child2: public Base

{
};

Base* Base::make_object(const char* type_name)

{
    if (strcmp(type_name,
        typeid(Child1).raw_name()) == 0)
        return new Child1;
    else if (strcmp(type_name,typeid
        (Child2).raw_name()) == 0)
        return new Child2;
    else
    {
        throw exception
            ("unrecognized type name passed");
        return 0X00; // represent NULL
    }
}

     这一实现是非常直接的,它需要程序员在main_object中保存一个所有类的表。这就破坏了基类的封装性,因为基类必须知道自己的子类。

     一个更面向对象的方法类解决虚构造函数叫做标本实例。它的基本思想是程序中生成一些全局的实例。这些实例只再虚构造函数的机制中存在:

class Base

{
public:
    staticBase* make_object(const char* typename)
    {
        if (!exemplars.empty())
        {
            Base* end = *(exemplars.end());
            list::iterator iter = </BASE*>
                exemplars.begin();
            while (*iter != end)
            {
                Base* e = *iter++;
                if (strcmp(typename,
                    e->get_typename()) == 0)
                    returne->clone();
            }
        }
        return 0X00 // Represent NULL;
    }
    virtual ~Base() { };
    virtual const char* get_typename() const
    {
        return typeid(*this).raw_name();
    }
    virtual Base* clone() const = 0;
protected:
    static list exemplars; </BASE*>
};

list Base::exemplars; </BASE*>

// T must be a concrete class

// derived from Base, above

template

class exemplar: public T

{
public:
    exemplar()
    {
        exemplars.push_back(this);
    }
    ~exemplar()
    {
        exemplars.remove(this);
    }
};

class Child: public Base

{
public:
    ~Child()
    {
    }
    Base* clone() const
    {
        return new Child;
    }
};

exemplar Child_exemplar;

     在这种设计中,程序员要创建一个类的时候要做的是创建一个相应的exampler类。注意到在这个例子中,标本是自己的标本类的实例。这提供了一种高校得实例化方法。

    5、创建一个缺省构造函数

     当继承被使用的时候,却省构造函数就会被调用。更明确地说,当继承层次的最晚层的类被构造的时候,所有基类的构造函数都在派生基类之前被调用,举个例子来说,看下面的代码:

#include

class Base

{
    int x;
public :
    Base() : x(0) { } // The NULL constructor
    Base(int a) : x(a) { }
};

class alpha : virtual public Base

{
    int y;
public :
    alpha(int a) : Base(a), y(2) { }
};

class beta : virtual public Base

{
    int z;
public :
    beta(int a) : Base(a), z(3) { }
};

class gamma : public alpha, public beta

{
    int w;
public :
    gamma ( int a, int b) : alpha(a), beta(b), w(4) { }
};

main()

{.....

}

     在这个例子中,我们没有在gamma的头文件中提供任何的初始化函数。编译器会为基类使用缺省的构造函数。但是因为你提供了一个构造函数,编译器就不会提供任何缺省构造函数。正如你看到的这段包含缺省构造函数的代码一样,如果删除其中的缺省构造函数,编译就无法通过。

     如果基类的构造函数中引入一些副效应的话,比如说打开文件或者申请内存,这样程序员就得确保中间基类没有初始化虚基类。也就是,只有虚基类的构造函数可以被调用。

    虚基类的却省构造函数完成一些不需要任何依赖于派生类的参数的初始化。你加入一个init()函数,然后再从虚基类的其他函数中调用它,或在其他类中的构造函数里调用(你的确保它只调用了一次)。

    6、不能取得构造函数的地址

     C++中,不能把构造函数当作函数指针来进行传递,指向构造函数的的指针也不可以直接传递。允许这些就可以通过调用指针来创建对象。一种达到这种目的的方法是借助于一个创建并返回新对象的静态函数。指向这样的函数的指针用于新对象需要的地方。下面是一个例子:

class A

{
public:
    A( ); // cannot take the address of this
    // constructor directly
    static A* createA();
    // This function creates a new A object
    // on the heap and returns a pointer to it.
    // A pointer to this function can be passed
    // in lieu of a pointer to the constructor.
};

     这一方法设计简单,只需要将抽象类置入头文件即可。这给new留下了一个问题,因为准确的类型必须是可见的。上面的静态函数可以用来包装隐藏子类。

    7、位拷贝在动态申请内存的类中不可行

     C++中,如果没有提供一个拷贝构造函数,编译器会自动生成一个。生成的这个拷贝构造函数对对象的实例进行位拷贝。这对没有指针成员的类来说没什么,但是,对用了动态申请的类就不是这样的了。为了澄清这一点,设想一个对象以值传递的方式传入一个函数,或者从函数中返回,对象是以为拷贝的方式复制。这种位拷贝对含有指向其他对象指针的类是没有作用的(见图2)。当一个含有指针的类以值传递的方式传入函数的时候,对象被复制,包括指针的地址,还有,新的对象的作用域是这个函数。在函数结束的时候,很不幸,析构函数要破坏这个对象。因此,对象的指针被删除了。这导致原来的对象的指针指向一块空的内存区域-一个错误。在函数返回的时候,也有类似的情况发生。

    图2. The automatic copy constructor that makes a bitwise copy of the class.

    这个问题可以简单的通过在类中定义一个含有内存申请的拷贝构造函数来解决,这种靠叫做深拷贝,是在堆中分配内存给各个对象的。

    8、编译器可以隐式指定强制构造函数

     因为编译器可以隐式选择强制构造函数,你就失去了调用函数的选择权。如果需要控制的话,不要声明只有一个参数的构造函数,取而代之,定义helper函数来负责转换,如下面的例子:

#include

#include

class Money

{
public:
    Money();
    // Define conversion functions that can only be
    // called explicitly.
    static Money Convert( char * ch )
    { return Money( ch ); }
    static Money Convert( double d )
    { return Money( d ); }
    void Print() { printf( "/n%f", _amount ); }
private:
    Money( char *ch ) { _amount = atof( ch ); }
    Money( double d ) { _amount = d; }
    double _amount;
};

void main()

{
    // Perform a conversion from type char *
    // to type Money.
    Money Account = Money::Convert( "57.29" );
    Account.Print();
    // Perform a conversion from type double to type
    // Money.
    Account = Money::Convert( 33.29 );
    Account.Print();
}

     在上面的代码中,强制构造函数定义为private而不可以被用来做类型转换。然而,它可以被显式的调用。因为转换函数是静态的,他们可以不用引用任何一个对象来完成调用。

     总结

     要澄清一点是,这里提到的都是我们所熟知的ANSI C++能够接受的。许多编译器都对ANSI C++进行了自己的语法修订。这些可能根据编译器的不同而不同。很明显,许多编译器不能很好的处理这几点。探索这几点的缘故是引起编译构造的注意,也是在 C++标准化的过程中移除一些瑕疵。

     参考文献:

    1. Stroustrup, Bjarne. The C++ Programming Language, 3rd ed., Addison-Wesley, Reading, MA, 1997. 2. Ellis, Margaret and Bjarne Stroustrup. The Annotated C++ Reference Manual, Addison-Wesley, Reading, MA, 1990. 3. Stroustrup, Bjarne. The Design and Evolution of C++, Addison-Wesley, Reading, MA, 1994. 4. Murry, Robert B. C++ Strategies and Tactics, Addison-Wesley, Reading, MA, 1993. 5. Farres-Casals, J. "Proving Correctness of Constructor Implementations," Mathematical Foundations of Computer Science 1989 Proceedings. 6. Breymann, Ulrich. Designing Components with the C++ STL, Addison-Wesley, Reading, MA,1998. 7. Lippman, Stanley and Josee LaJoie. C++ Primer, 3rd ed., Addison-Wesley, Reading, MA, 1998. 8. Skelly, C. "Getting A Handle On The New-Handler," C++ Report, 4(2):1-18, February 1992. 9. Coggins, J. M. "Handling Failed Constructors Gracefully," C++ Report, 4(1):20-22, January 1992. 10. Sabatella, M. "Laser Evaluation of C++ Static Constructors," SIGPLAN Notices, 27(6):29-36 (June 1992). 11. Eckel, B. "Virtual Constructors," C++ Report, 4(4):13-16,May 1992. 12. Coplien, James O. Advanced C++: Programming Styles and Idioms, Addison-Wesley, Reading, MA, 1992.

注:原文出处  http://www.cnblogs.com/safeking/archive/2005/12/20/300717.html

现代C++如何高效地设计构造函数 本文面向不太清楚C++11以后的各种语义的新手,希望从较为浅显的角度解释一些现代C++实践中的编程规范及其原因。 阅读详情

相关推荐

C++:构造函数作用及用法

PS:写在前面 就是构造函数的作用可以这样理解,如果没有构造函数就是类里边只是声明了成员变量,成员函数,还有最后的对象,这样你在对该对象进行初始化赋值时就比较麻烦就得先调用成员函数对成员变量赋值,成员变量进而作用到对象上,之后有了构造函数,在构建构造函数时直接可以带参数对对象进行初始化,相当于省略了步骤,可以这样简单的理解。 PS:但是构造函数远远不止只有赋值这一条作用(此处不要陷入误区以为他就是给成员变量赋值的这一个作用,不是这样的或者说不完全是这样,给成员变量赋值只是构造函数的作用之一,他还有其

m0_37957160的博客 6984

论C++构造函数中的不合理设计 (转)

论C++构造函数中的不合理设计 (转)[@more@]论C++构造函数中的不合理设计 作者:张岩 发布时间:2001/03/20 文章摘要:   在C++中,构造函数是一个在构建对象的时候调用的特殊的函数,其目的是对对象进行...

csd3176的博客 92

整理并记录几种运算放大器

运算放大器是一种十分常见的电子元器件,最近我在学习运放,以前在学校没有好好的学习,今天在B站看了唐老师讲运算放大器-唐老师讲电赛系列视频教程,记录下所学的,纯当是自己的笔记 学习运放,有两个重要的概念及重要的计算法宝,虚短vp=vn;和虚断ip=in 1反向比例运算电路 Rf可以大于、小于或等于R,起到放大、跟随、衰减输入的作用; 平衡电阻没有太高的精度要求,可加可不加; 有些运放内部集成了补偿电路,就不需要使用平衡电阻,加了反而增大误差,如OPA227 2.同向比例运放电路 .

qq_36823004的博客 6364

从构造函数到Vue3响应式:C++中“常量转特殊类型”的隐藏大招

文章摘要:本文揭示了C++构造函数背后的深层设计模式——"传入普通常量,返回特殊类型",并将其应用于反调试和响应式开发场景。通过分析构造函数的"无名类型生成器"本质,作者展示了如何将这一模式泛化为通用的"功能化包装函数"。在反调试中实现引用隐藏,在响应式开发中复刻Vue3的ref机制,并与Java包装类形成跨语言印证。文章用"幽灵-宿主"比喻阐释临时对象特性,最终通过Linux虚拟机OVA文件的类比,完整呈现了从基础语法到高级应

weixin_56334307的博客 880

基于AI Agent的数据治理实战:从架构设计到企业级落地

数据治理是确保企业数据质量、一致性与安全性的核心实践,其核心原理在于通过规范、流程与技术工具对数据进行全生命周期管理。传统人工治理模式效率低下且难以规模化,而大语言模型(LLM)与智能体(Agent)技术的发展,为数据治理的自动化与智能化带来了突破。通过将自然语言理解、任务规划与工具调用能力相结合,AI Agent能够将治理规则“代码化”与“智能化”,实现从被动响应到主动发现的模式转变。在应用场景上,AI Agent可扮演智能数据专员角色,自动执行元数据问答、数据质量探查、口径对齐等任务,显著提升数据团队效

weixin_34008805的博客 418

倍福TC3 PLC高速采集实战:如何用PLC-Recorder实现0.24ms级时间戳同步

本文详细介绍了倍福TC3 PLC与PLC-Recorder实现0.24ms级时间戳同步的工程实践方案。通过硬件拓扑设计、时间源选择优化、报文结构封装及同步验证方法,为工业自动化领域的高精度数据采集提供了可靠解决方案,特别适用于精密装配、激光切割等微秒级同步要求的场景。

weixin_29193359的博客 372

C++类的多种构造函数

移动构造 拷贝构造 默认构造

wtl666_6的博客 1万+

LightGBM学习笔记

LightGB学习笔记1. lightgbm概述1.1 lightgbm介绍1.2 lightgbm和xgboost对比2 .直方图算法及改进2.1 直方图算法2.2 直方图算法改进2.2.1 GOSS算法3.树的生长策略4.系统设计5. 实战 lightgbm是基于boosting的学习框架,使用的是基于决策树的学习算法,具有更快的训练速度、更低的内存使用、更高的正确率、并且能够支持并行化学习,可以用来处理大规模数据,本文主要是针对学习视频https://www.bilibili.com/video/BV

一一xi的博客 3304

C++类的构造函数

详细讲解C++类中的构造函数,包含各种细节,一次讲明白!

长岛冰茶去冰的博客 1万+

避开这些坑!STM32H750 IAP升级实战:从Bootloader设计到APP接收的完整避坑指南

本文深入探讨STM32H750 IAP升级的完整避坑指南,从Bootloader设计到APP接收的全流程实践。特别针对QSPI Flash运行限制、SRAM跳转机制和固件校验等核心问题,提供工业级解决方案,帮助开发者提升升级成功率和系统稳定性。

weixin_30471561的博客 275

【华为OD机试真题】6、数组去重和排序 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

题目描述 >给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序

KJ.JK 3888

【C++】构造函数 利用构造函数对类对象进行初始化

有关构造函数与析构函数的知识点

TPON的博客 1万+

【深度学习基础】多任务学习(Multi-Task Learning)

多任务学习(Multi-task learning)是和单任务学习(single-task learning)相对的一种机器学习方法。在机器学习领域,标准的算法理论是一次学习一个任务,也就是系统的输出为实数的情况。复杂的学习问题先被分解成理论上独立的子问题,然后分别对每个子问题进行学习,最后通过对子问题学习结果的组合建立复杂问题的数学模型。多任务学习是一种联合学习,多个任务并行学习,结果相互影响。一次只学习一个任务(task),大部分的机器学习任务都属于单任务学习。

十二月的猫 1万+

C++——拷贝构造函数

(用旧对象去构造新对象)拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构造及初始化。值类型(不行,会产生递归);指针类型(能实现要求,但会出现歧义(感觉a的地址给b构造));引用类型(本类对象的const引用)。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。

weixin_59179454的博客 2万+

【Flink on k8s】- 1 - Flink Kubernetes Operator 简介 2023

Flink Kubernetes Operator 可以与 Kubernetes 的其他功能和工具集成,可以帮助用户快速定位和解决问题。Flink Kubernetes Operator可以在Kubernetes上实现高可用性,以确保 Flink 集群的稳定性和可靠性。Flink Kubernetes Operator 可以快速地部署 Flink 集群,而无需手动配置和管理集群。Flink Kubernetes Operator可以将Flink集群与其他应用程序隔离,以避免资源争用和干扰。

欢迎来到我的博客,一起探索代码里的世界! 1345

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++中构造函数的超详细讲解

详细讲解C++种的构造函数

guishangppy的博客 9747

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++构造函数中的不合理设计

构造函数介绍在C++中,构造函数是一个在构件对象的时候调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。比如说,限定构造函数名称与类的名称相同的条件。这些特性在构造C++编译器的时候是值得引起注意的。还有,在今后C++的标准修订或者制定其他面向对象的设计语言时候应当避免这些特性。这里也提出了一些解决

armman的专栏 1110

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【C++】构造函数与析构函数

C++构造函数和析构函数

明朗晨光的专栏 5426

论C++构造函数中的不合理设计

论C++构造函数中的不合理设计 作者:张岩 发布时间:2001/03/20 文章摘要:  在C++中,构造函数是一个在构建对象的时候调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。本文对这些问题进行了探讨,并提出了一些解决的方

CandyCat的专栏 1553

cpp——类——构造函数

概述 为了类的使用方便,类的设计尽可能使类的使用方式与内置类型无区别,构造函数则是类模仿内置类型的初始化 内置类型初始化支持直接初始化,复制初始化,默认初始化,构造函数对应于内置类型的各种初始化: 带参数构造函数——直接初始化 复制构造函数——复制初始化 默认构造函数——默认初始化 构造函数特点: 函数名与类名同名,用来标记和识别构造函数 没有返回值,构造函数是对自身的初始化,返回值无意义,因为没有返回值的接收者 初始化行为,构造函数在生成(定义)对象时自动调用,因此构造函数只能执行一次,否则就多次初始化

mardax的专栏 3519

C++的构造函数

博主个人认为构造函数就是创建对象时 对即将创建的对象进行预处理的函数。这个预处理一般是给对象的成员进行赋值。自定义的默认构造函数就是无参的构造函数如图2_1所示。图2_1自定义默认构造函数有自定义的默认构造函数时,合成的默认构造函数就不会使用。自定义拷贝构造函数的声明如图4_1所示。图4_1自定义拷贝构造函数的定义如图4_2所示。图4_2在自定义拷贝构造函数中,面对指针类型的成员我们是可以设计深拷贝的逻辑的当然,针对有指针类型的类设计拷贝构造函数时,设计深拷贝逻辑是非常有必要的,

m0_61756911的博客 1910

再谈C++中的构造函数,深入理解构造函数(上篇)

前言 其实两个月前我写过一篇C++基础文章:关于构造函数的基本用法,文章链接传送门????:c++基础 面向对象:第五篇(构造,析构,拷贝函数),但是,这里仅仅是基础中的用法,并没有涉及太多的讲解,打算今天整理以下,我对构造函数的再度理解,分享给大家。 文章目录前言构造函数的作用,存在意义,目的隐式转化和explicit 构造函数的作用,存在意义,目的 构造函数的作用,存在意义,目的:用来初始化类对象的成员变量的函数 如何理解呢?其实就是为了封装性(我的理解),当我们定义一个类对象时候,其实可以在类外直接

呋喃吖的博客 1420

C++构造函数总结

一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 #include <iostream> using namespace std; class CExample { private:  int a; public: //构造函数  CExample(int b)

浩瀚之水的专栏 3721

论c++构造函数中的不合理设计

<br />论c++构造函数中的不合理设计<br /> 作者:张岩  <br />   在c++中,构造函数是一个在构件对象的时候调用的特殊的函数,其目的是对对象进<br /> 行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的<br /> 设计并不完美,甚至有些不合理的特性。比如说,限定构造函数名称与类的名称相同的<br /> 条件。这些特性在构造c++编译器的时候是值得引起注意的。还有,在今后c++的标准修<br /> 订或者制定其他面向对象的设计语言时候应当避免这

Programer From Scrach 837

C++构造函数——对象生命的起点与设计的艺术

本文深入探讨了C++中构造函数的本质与多种形态。构造函数是类中特殊的成员函数,负责对象初始化,确保对象创建时处于合法状态。文章分析了默认构造函数、参数化构造函数和拷贝构造函数三种主要形态:默认构造函数实现无参初始化;参数化构造函数支持定制化初始值;拷贝构造函数控制对象复制行为,避免浅拷贝问题。通过银行账户和字符串类的示例,文章展示了如何合理设计构造函数来保证对象安全性和资源管理,强调了显式定义构造函数的重要性,特别是涉及动态内存分配时需要实现深拷贝。最后指出构造函数不仅是语法特性,更是对象生命周期管理的关键

qq_39980997的博客 1056
上一篇: C++基本数据类型以及需要注意的地方
下一篇: 【转】Visual C++线程同步技术剖析:临界区,时间,信号量,互斥量
Linruin
博客等级 码龄19年 18粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值