C++函数 加括号与不加括号

很多时候,我们会看到一些在创建对象时有的加括号有的不加括号

那么,这是什么情况呢?

总结:函数需要加上括号,加上括号会对函数初始化,不加括号可能导致未知错误

我们来验证一下。

1.基本数据类型不带括号()

#include <iostream>
using namespace std;int main(int arg, char **argv)
{int a;cout << "a=" << a << endl;return 0;
}
调试结果:

2.基本数据类型带括号()

#include <iostream>
using namespace std;int main(int arg, char **argv)
{int a();   // 这是一个返回值为 int 无参数的函数;return 0;
}
调试结果: 看注释

3.基本数据类型new创建不带括号()

#include <iostream>
using namespace std;int main(int arg, char **argv)
{int *a = new int;cout << "a=" << *a << endl;return 0;
}
调试结果:这是个随机值

4.基本数据类型new创建带括号()

#include <iostream>
using namespace std;int main(int arg, char **argv)
{int *a = new int();cout << "a=" << *a << endl;return 0;
}
调试结果:被初始化为 0

5.自定义数据类型不带括号(),不提任何供构造函数

#include <iostream>
using namespace std;class A {
public:int value;
};int main(int arg, char **argv)
{A a;cout << "value=" << a.value << endl;return 0;
}
调试结果:

6.自定义数据类型带括号(),不提任何供构造函数

#include <iostream>
using namespace std;class A {
public:int value;
};int main(int arg, char **argv)
{A a(); // 这是一个返回值类型为A的无参数函数return 0;
}
调试结果: 看注释

7.自定义数据类型new创建不带括号(),不提任何供构造函数

#include <iostream>
using namespace std;class A {
public:int value;
};int main(int arg, char **argv)
{A *a = new A;cout << "value=" << a->value << endl;return 0;
}
调试结果:

8.自定义数据类型new创建带括号(),不提任何供构造函数

#include <iostream>
using namespace std;class A {
public:int value;
};int main(int arg, char **argv)
{A *a = new A();cout << "value=" << a->value << endl;return 0;
}
调试结果:

9.自定义数据类型不带括号(),提供构造函数

#include <iostream>
using namespace std;class A {
public:A() {};public:int value;
};int main(int arg, char **argv)
{A a;cout << "value=" << a.value << endl;return 0;
}
调试结果:

10.自定义数据类型带括号(),提供构造函数

#include <iostream>
using namespace std;class A {
public:A() {};public:int value;
};int main(int arg, char **argv)
{A a();// 这是一个返回值类型为A的无参数函数//cout << "value=" << a.value << endl;return 0;
}
调试结果: 看注释

11.自定义数据类型new创建不带括号(),提供构造函数

#include <iostream>
using namespace std;class A {
public:A() {};public:int value;
};int main(int arg, char **argv)
{A *a = new A;cout << "value=" << a->value << endl;return 0;
}
调试结果:

12.自定义数据类型new创建带括号(),提供构造函数

#include <iostream>
using namespace std;class A {
public:A() {};public:int value;
};int main(int arg, char **argv)
{A *a = new A();cout << "value=" << a->value << endl;return 0;
}
调试结果:

13.自定义数据类型new创建带括号(),提供构造函数,并是全局对象

#include <iostream>
using namespace std;class A {
public:A() {};public:int value;
};A *a = new A();
int main(int arg, char **argv)
{	cout << "value=" << a->value << endl;return 0;
}
调试结果:

总结: 在编写类时,只有在不给该类显式提供构造函数并在 new 对象加上括号()时, 其类内部数据成员才会被定义,其余情况都是未定义行为!

尽量为该类编写构造函数并进行一系列的初始化和赋值操作,不要依赖系统默认未定义行为。

尽量为该类编写构造函数并进行一系列的初始化和赋值操作,不要依赖系统默认未定义行为。

尽量为该类编写构造函数并进行一系列的初始化和赋值操作,不要依赖系统默认未定义行为。


首先讨论各种构造函数

我们都知道,当我们不提供构造函数时,编译器会自动为我们添加一个默认无参构造函数和一个默认拷贝构造函数,例如:

class test {};
int main() {
    test A;//调用默认无参构造
    test B(A);//调用默认拷贝构造
    return 0;
}


当我们添加无参构造函数或者有参构造函数时,编译器将不再提供默认无参构造函数和但依旧会提供默认拷贝构造函数,例如:

//添加无参构造函数时
class test {
public:
    test() { cout << "无参构造" << endl;}
};
int main() {
    test A;//输出:无参构造
    test B(A);//无输出,调用默认拷贝构造
    return 0;
}


//添加有参构造函数时
class test {
public:
    int val;
    test(int _val) {
        val = _val;
        cout << "有参构造" << endl;
    }
};
int main() {
    //test A; 无法通过编译,此时没有无参构造
    test A(5);//输出:有参构造
    test B(A);//无输出,调用默认拷贝构造
    return 0;
}


而当我们添加拷贝构造函数时,编译器将不再提供任何默认构造函数,例如:

class test {
public:
    int val;
    test(int _val) {
        this->val = _val;
        cout << "有参构造" << endl;
    } //必须得添加无参构造或者有参构造,不然没法创建新对象
    test(test& T) {
        this->val = T.val;
        cout << "拷贝构造" << endl;
    }
};
int main() {
    //test A; 无法通过编译,此时没有无参构造。
    test A(5);//输出:“有参构造”
    test B(A);//输出:“拷贝构造”
    return 0;
}


新建对象时,如果使用无参构造,不添加括号。如果添加括号,编译器会认为这是函数申明,例如:

Test A;
Test A();//错误,此时编译器会认为这是函数申明,而不是无参构造


然后是new创建对象时是否添加括号

new创新新对象时,如果是内置类型,例如:int,是否添加括号都可以,添加括号会进行初始化,不添加则只是开辟空间。例如:

int* T = new int;//创建新对象,只是开辟空间
int* T = new int();//创建新对象并初始化

而对于new创建自定义对象时是否加括号,区别可以参见new对象加括号和不加括号的区别。总结就是,new创建新对象时最好加上括号。


当函数指针被赋值给另一个变量时函数调用不需要加括号

当函数指针被赋值给另一个变量时,函数调用不需要加括号是因为函数名本身就代表了函数的地址。通过将函数指针赋值给另一个变量,实际上是将函数的地址赋值给了这个变量。因此,可以直接通过这个变量来调用函数,而不需要使用括号。

这种方式可以用于实现回调函数或者动态选择要调用的函数的场景。通过将不同的函数指针赋值给同一个变量,可以在运行时决定要调用的具体函数,从而实现灵活的程序逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/538354.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端框架vue的样式操作,以及vue提供的属性功能应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

关于tcp协议

目录 前言&#xff1a; 一、TCP协议的基本概念&#xff1a; 二、TCP协议的主要特点&#xff1a; 2.1面向连接&#xff1a; 2.2可靠传输&#xff1a; 2.3基于字节流&#xff1a; 三、TCP连接的建立与终止&#xff1a; 3.1连接建立&#xff1a; 3.1.1SYN&#xff1a; 3…

Linux系统部署Swagger Editor结合内网穿透实现公网管理本地接口文档

文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagger Editor2. Linux安装Cpolar3. 配置Swagger Editor公网地址4. 远程访问Swagger Editor5. 固定Swagger Editor公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xf…

保护IP地址安全:维护网络安全

在今天的数字化时代&#xff0c;IP地址是互联网通信的基础&#xff0c;也是网络安全的重要组成部分。保护IP地址安全至关重要&#xff0c;因为恶意攻击者可能利用IP地址进行网络入侵、数据泄露、服务拒绝等攻击。因此&#xff0c;制定有效的保护措施&#xff0c;维护IP地址的安…

【C++进阶】C++关联式容器map和set用法详解

map和set用法详解 一&#xff0c;关联式容器二&#xff0c;键值对pair三&#xff0c;set1. set的用法2. multiset的用法 四&#xff0c;map1. 键值对pair的介绍2. map用法3. multimap用法 五&#xff0c;总结 上一节我们讲解了二叉搜索树&#xff0c;在讲解之前我们先来讲一下s…

Redis实现分布式锁源码分析

为什么使用分布式锁 单机环境并发时&#xff0c;使用synchronized或lock接口可以保证线程安全&#xff0c;但它们是jvm层面的锁&#xff0c;分布式环境并发时&#xff0c;100个并发的线程可能来自10个服务节点&#xff0c;那就是跨jvm了。 简单分布式锁实现 SETNX 格式&…

柚见第十期(后端队伍接口详细设计)

创建队伍 用户可以 创建 一个队伍&#xff0c;设置队伍的人数、队伍名称&#xff08;标题&#xff09;、描述、超时时间 P0 队长、剩余的人数 聊天&#xff1f; 公开 或 private 或加密 信息流中不展示已过期的队伍 请求参数是否为空&#xff1f;是否登录&#xff0c;未登录不…

力扣每日一题 合并后数组中的最大元素 贪心

Problem: 2789. 合并后数组中的最大元素 思路 贪心&#xff1a;从右向左合并&#xff0c;尽可能的多合并&#xff0c;直到不能合并&#xff0c;更新答案&#xff0c;找前一阶段的最大合并值 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code …

Umi - 刷新后页面报404

Umi 项目本地运行刷新没问题&#xff0c;但是部署之后刷新页面报404。因为Umi 默认是用 browser 模式&#xff0c;需要做一下处理。 以下是官方给出解决方案。 一、解决方案 1. 方案一&#xff1a;改用hashHistory .umirc.js {history: { type: hash }, }这个方案项目打包…

如何从任何文档生成指令数据集以进行LLM微调

使用轻量级库经济地生成高质量的合成数据集 大型语言模型 &#xff08;LLMs&#xff09; 是功能强大的通用工具&#xff0c;但它们通常缺乏特定于领域的知识&#xff0c;这些知识通常存储在企业存储库中。 使用您自己的数据微调自定义LLM可以弥合这一差距&#xff0c;而数据准…

如何在Linux部署Docker Registry本地镜像仓库并实现无公网IP远程连接

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

子查询 封装属性创建Connection连接类 数据库连接池

子查询 在select语句中包含另一个select 语句 -->子查询 子查询的分类 单行单列子查询 在where子句中使用 运算符 ! > < -- 查询工资比公司平均工资高的员工信息 -- 查询与员工’smith‘同职位的员工信息 -- 查询比员工joins入职…