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.mzph.cn/news/743358.shtml

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

相关文章

利用Python进行网络爬虫:Beautiful Soup和Requests的应用【第131篇—Beautiful Soup】

利用Python进行网络爬虫&#xff1a;Beautiful Soup和Requests的应用 在网络数据变得日益丰富和重要的今天&#xff0c;网络爬虫成为了获取和分析数据的重要工具之一。Python作为一种强大而灵活的编程语言&#xff0c;在网络爬虫领域也拥有广泛的应用。本文将介绍如何使用Pyth…

Elasticseach基础认识

ES的起源&#xff1f; Elasticsearch 是由 Elastic 公司创建 简称&#xff08;ES&#xff09; Elasticsearch 是一个分布式、免费和开放的搜索和分析引擎&#xff0c;适用于所有类型的数据&#xff0c;包括文本、数字、地理空间、结构化和非结构化数据。 Elasticsearch 基于 …

Oracle 主从切换脚本

一、 切换前预检查 1. dg_precheck_main_v1.4.sh #!/bin/bash#********************************************************************************** # Author: Hehuyi_In # Date: 2022年06月16日 # FileName: dg_precheck_main_v1.4.sh # # For sys user, execute the sc…

LLM之RAG实战(二十九)| 探索RAG PDF解析

对于RAG来说&#xff0c;从文档中提取信息是一种不可避免的场景&#xff0c;确保从源文件中提取出有效的内容对于提高最终输出的质量至关重要。 文件解析过程在RAG中的位置如图1所示&#xff1a; 在实际工作中&#xff0c;非结构化数据比结构化数据丰富得多。如果这些海量数据无…

如何使用vue定义组件之——子组件调用父组件数据

1.定义父子模板template <div class"container"><my-father></my-father><my-father></my-father><my-father></my-father><!-- 此处无法调用子组件&#xff0c;子组件必须依赖于父组件进行展示 --><!-- <my-…

数学实验_Matlab使用2_简单绘图

简单使用 x -pi * 2 : .1 : pi*2;y sin(x);plot(x, y); % 绘制普通图像plot(x, y, k-.*); % 绘制2维图像&#xff0c;线为实线&#xff0c;*为每个点&#xff08;Matlab的画图比较原始&#xff0c;就是简单的秒点画图&#xff09;grid on; % 打开网状格式% grid off; % 关闭…

SORA和大语言模型的区别

OpenAI的文生视频模型SORA与大语言模型&#xff08;LLM&#xff09;的主要区别在于它们的应用领域和处理的数据类型&#xff0c;数据处理能力、技术架构、多模态能力和创新点。SORA作为一款专注于视频生成的模型&#xff0c;展现了在处理视觉数据方面的独特优势和创新能力。 1…

R语言读取大型NetCDF文件

失踪人口回归&#xff0c;本篇来介绍下R语言读取大型NetCDF文件的一些实践。 1 NetCDF数据简介 先给一段Wiki上关于NetCDF的定义。 NetCDF (Network Common Data Form) is a set of software libraries and self-describing, machine-independent data formats that support…

STM32串口通信—串口的接收和发送详解

目录 前言&#xff1a; STM32串口通信基础知识&#xff1a; 1&#xff0c;STM32里的串口通信 2&#xff0c;串口的发送和接收 串口发送&#xff1a; 串口接收&#xff1a; 串口在STM32中的配置&#xff1a; 1. RCC开启USART、串口TX/RX所对应的GPIO口 2. 初始化GPIO口 …

YOLOv8改进 | 图像去雾 | 特征融合注意网络FFA-Net增强YOLOv8对于模糊图片检测能力(北大和北航联合提出)

一、本文介绍 本文给大家带来的改进机制是由北大和北航联合提出的FFA-net: Feature Fusion Attention Network for Single Image Dehazing图像增强去雾网络,该网络的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接恢复无雾图像,FFA-Net通过特征…

MyBatis-Plus学习记录

目录 MyBatis-Plus快速入门 简介 快速入门 MyBatis-Plus核心功能 基于Mapper接口 CRUD 对比mybatis和mybatis-plus&#xff1a; CRUD方法介绍&#xff1a; 基于Service接口 CRUD 对比Mapper接口CRUD区别&#xff1a; 为什么要加强service层&#xff1a; 使用方式 CR…

开发指南009-从list导出excel文件

从数据库返回一般是对象的列表&#xff0c;平台底层提供了从list转为excel文件的方法。平台的设计思想就是为一些典型的场景设计对应的解决方法&#xff0c;通过模式化的方法来简化编程和提高维护性&#xff08;通过标准化来减少学习成本和维护成本&#xff0c;张三做的东西和李…

游戏数据处理

游戏行业关键数据指标 ~ 总激活码发放量、总激活量、总登录账号数 激活率、激活登录率 激活率 激活量 / 安装量 激活率 激活量 / 激活码发放量 激活且登录率 激活且登录量 / 激活码激活量 激活且登录率应用场景 激活且登录率是非常常用的转化率指标之一&#xff0c;广泛…

Ypay源支付6.9无授权聚合免签系统可运营源码

YPay是一款专为个人站长设计的聚合免签系统&#xff0c;YPay基于高性能的ThinkPHP 6.1.2 Layui PearAdmin架构&#xff0c;提供了实时监控和管理的功能&#xff0c;让您随时随地掌握系统运营情况。 说明 Ypay源支付6.9无授权聚合免签系统可运营源码 已搭建测试无加密版本…

HTML5:七天学会基础动画网页13

看完前面很多人可能还不是很明白0%-100%那到底是怎么回事&#xff0c;到底该怎么用&#xff0c;这里我们做一个普遍的练习——心跳动画 想让心❤跳起来&#xff0c;我们先分析一波&#xff0c;这个心怎么写&#xff0c;我们先写一个正方形&#xff0c;再令一个圆形前移: 再来一…

Linux中YUM仓库的配置

Linux软件包的管理 YUM仓库是什么YUM的常用命令修改YUM源其实CentOS7已经对YUM做了优化 YUM仓库是什么 之前传统RPM的管理方式 可以简单理解为写Java的时候不用Maven管理 jar包都要自己手动去导入 去下载 但是配置好YUM仓库 就放佛在用Maven管理Java项目 基于RPM包管理 能够从…

Python导入类说一说

要在Python中导入一个类&#xff0c;需要使用import关键字。 详细去看下面的代码 1、多例类 class Restaurant:餐馆类def __init__(self,restaurant_name,cuisine_type):#类的属性self.restaurant_name restaurant_nameself.cuisine_type cuisine_type# self.stregth_leve…

2024软件测试应该学什么?“我“怎么从功能转入自动化测试?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试应该学…

TypeScript编译选项

编译单个文件&#xff1a;终端 tsc 文件名 自动编译单个文件&#xff1a;终端 tsc 文件名 -w 编译整个项目&#xff1a;tsc 前提是得有ts的配置文件tsconfig.json 自动编译整个项目&#xff1a;tsc --w tsconfig.json默认文件内容&#xff1a; tsconfig.json是ts编译器的配…

代码随想录算法训练营Day45 ||leetCode 70. 爬楼梯 (进阶)|| 322. 零钱兑换 || 279.完全平方数

70. 爬楼梯 &#xff08;进阶&#xff09; 本质上和leetcode377一样 #include <iostream> #include <vector> using namespace std; int main() {int n, m;while (cin >> n >> m) {vector<int> dp(n 1, 0);dp[0] 1;for (int i 1; i < n; i…