C++11中default的使用

本文介绍了C++11中的Defaulted函数特性,包括defaulted函数如何减轻程序员负担并提高代码执行效率。文中还提供了多种场景下的示例代码,帮助理解defaulted和deleted函数的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C+11中,对于defaulted函数,编译器会为其自动生成默认的函数定义体,从而获得更高的代码执行效率,也可免除程序员手动定义该函数的工作量。

C++的类有四类特殊成员函数,它们分别是:默认构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符。这些类的特殊成员函数负责创建、初始化、销毁,或者拷贝类的对象。如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员函数时,则编译器会隐式的为这个类生成一个默认的特殊成员函数。当存在用户自定义的特殊成员函数时,编译器将不会隐式的自动生成默认特殊成员函数,而需要程序员手动编写,加大了程序员的工作量。并且手动编写的特殊成员函数的代码执行效率比编译器自动生成的特殊成员函数低。

C++11标准引入了一个新特性:defaulted函数。程序员只需在函数声明后加上”=default;”,就可将该函数声明为defaulted函数,编译器将为显式声明的defaulted函数自动生成函数体。

defaulted函数特性仅适用于类的特殊成员函数,且该特殊成员函数没有默认参数。

defaulted函数既可以在类体里(inline)定义,也可以在类体外(out-of-line)定义。

In C++11, defaulted and deleted functions give you explicit control over whether the special member functions are automatically generated.

“=default” instructs the compiler to generate the default implementation for the function. Defaulted functions have two advantages: They are more efficient than manual implementations, and they rid the programmer from the chore of defining those functions manually.

By default, C++ will provide a default constructor, copy constructor, copy assignment operator (operator=) and a destructor. If you provide alternate versions of any of these functions for your class, C++ will not provide a default version. However, in C++11, you can now specify that you would like the compiler to provide a default one anyway. This is done by prototyping the function and using the default specifier.

The default specifier can only be used with functions that have a default.

=default: it means that you want to use the compiler-generated version of that function, so you don't need to specify a body.

=delete: it means that you don't want the compiler to generate that function automatically.

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "default.hpp"
#include <iostream>

////////////////////////////////////////////////
// reference: http://www.learncpp.com/cpp-tutorial/b-6-new-virtual-function-controls-override-final-default-and-delete/
class Foo
{
	Foo(int x); // Custom constructor
	Foo() = default; // The compiler will now provide a default constructor for class Foo as well
};

/////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/language/default_constructor
struct A
{
	int x;
	A(int x = 1) : x(x) {} // user-defined default constructor
};

struct B : A
{
	// B::B() is implicitly-defined, calls A::A()
};

struct C
{
	A a;
	// C::C() is implicitly-defined, calls A::A()
};

struct D : A
{
	D(int y) : A(y) {}
	// D::D() is not declared because another constructor exists
};

struct E : A
{
	E(int y) : A(y) {}
	E() = default; // explicitly defaulted, calls A::A()
};

struct F
{
	int& ref; // reference member
	const int c; // const member
	// F::F() is implicitly defined as deleted
};

int test_default1()
{
	A a;
	B b;
	C c;
	// D d; // compile error
	E e;
	// F f; // compile error

	return 0;
}

///////////////////////////////////////////////////////
// reference: https://msdn.microsoft.com/zh-cn/library/dn457344.aspx
struct widget
{
	widget() = default;

	inline widget& operator=(const widget&);
};

// Notice that you can default a special member function outside the body of a class as long as it’s inlinable.
inline widget& widget::operator=(const widget&) = default;

GitHubhttps://github.com/fengbingchun/Messy_Test

### C++ 中 `default` 关键字的使用方法 在 C++11 及之后的标准中,`default` 关键字被引入以允许开发者显式请求编译器为某些特殊成员函数生成默认实现。这使得程序设计者能够更加精确地控制类的行为。 #### 基本概念 当在一个类定义中指定某个特殊成员函数等于 `default` 时,表示该函数由编译器自动生成标准行为[^2]。这种机制适用于以下几种情况: - **默认构造函数** - **拷贝构造函数** - **移动构造函数** - **赋值运算符 (拷贝和移动)** - **析构函数** 这些函数通常被称为“特殊成员函数”,因为它们是由编译器自动合成的。 --- #### 示例代码解析 以下是通过具体示例展示如何使用 `default` 关键字: ```cpp #include <iostream> class MyClass { public: // 默认构造函数 MyClass() = default; // 拷贝构造函数 MyClass(const MyClass&) = default; // 移动构造函数 MyClass(MyClass&&) = default; // 赋值运算符 (拷贝) MyClass& operator=(const MyClass&) = default; // 赋值运算符 (移动) MyClass& operator=(MyClass&&) = default; // 析构函数 ~MyClass() = default; }; int main() { MyClass obj; // 调用默认构造函数 MyClass obj2(obj); // 调用拷贝构造函数 MyClass obj3(std::move(obj)); // 调用移动构造函数 return 0; } ``` 上述代码展示了如何利用 `default` 来让编译器生成所有必要的特殊成员函数。这样做的好处是可以减少手动编写重复代码的工作量,同时保持清晰性和一致性[^4]。 --- #### 特殊场景下的应用 ##### 场景一:仅需部分默认实现 如果只需要某些特殊成员函数而禁用其他,则可以通过组合 `default` 和 `delete` 实现这一目标。例如: ```cpp class NoCopyAllowed { private: int value; public: NoCopyAllowed(int v) : value(v) {} // 显式删除拷贝构造函数 NoCopyAllowed(const NoCopyAllowed&) = delete; // 显式删除赋值运算符 NoCopyAllowed& operator=(const NoCopyAllowed&) = delete; // 提供默认的移动语义 NoCopyAllowed(NoCopyAllowed&&) = default; NoCopyAllowed& operator=(NoCopyAllowed&&) = default; }; ``` 在此例子中,我们完全禁止了对象之间的复制操作,但仍然保留了高效的移动语义[^1]。 ##### 场景二:派生类中的覆盖 对于继承关系而言,在派生类中重新声明并标记为 `= default` 的情况下,会强制要求编译器基于当前上下文重新生成适合的版本。比如: ```cpp class Base { protected: std::string name; public: virtual void setName(const std::string& n) = 0; virtual ~Base() = default; }; class Derived : public Base { public: explicit Derived(const std::string& initialName) : name(initialName) {} // 继承虚函数的具体实现 void setName(const std::string& n) override { this->name = n; } // 自动调用父类析构函数的同时也执行自己的清理工作 ~Derived() = default; }; ``` 这里可以看到即使存在多态特性的情况下,默认析构函数依然能正常运作。 --- #### 总结 `default` 是一种强大的工具,它不仅简化了开发流程还增强了代码可读性与维护便利度。合理运用它可以有效提升软件质量以及性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值