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创建新对象时最好加上括号。


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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二级指针作为函数参数——可以改变调用函数中传入指针的值(不是指向地址的值哦!)

主要是看这篇文章&#xff1a; 二级指针作为函数参数_二级指针做函数参数-CSDN博客 对里面的程序进行一些修改和补充&#xff0c;调试加更多说明。 1、一级指针情况&#xff1a; #include"stdio.h"int my_strlen1(const char* str) {int count 0;int i 0;if (N…

【功能大全】手机短信验证码一键注册登录流程

目录 发送验证码 注册登录 用户表设计 ​编辑申请腾讯云短信与密钥 找到云短信服务 开通腾讯云短信服务 ​编辑​​​​​创建短信签名 ​编辑​编辑创建短信正文模版​编辑​编辑 等待审核 测试短信​编辑 SDK密钥创建 SpringBoot集成腾讯云短信 pom中导入腾讯云短…

Uni-app跟学笔记(一):新建项目、运行、tabbar、全局配置

文章目录 1&#xff09;新建项目2&#xff09;项目运行3&#xff09;项目结构4&#xff09;开发规范5&#xff09;globalStyle全局外观配置6&#xff09;pages页面配置7&#xff09;tabbar8&#xff09;Condition 本博客为 uni-app 此门课的跟学笔记&#xff0c;目的是便于个人…

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

“书接上回”继续对transition补充&#xff0c;在检查中找到ease后&#xff0c;鼠标放到ease前的紫色小方块就可以对运动曲线进行调整&#xff0c;这个曲线叫贝塞尔曲线&#xff0c;这里不做别的补充&#xff0c;不用了解&#xff0c;我们只要知道这个运动方式不只是有简单的匀…

定时执行专家 —— 让工作更高效,生活更便捷

在现代社会&#xff0c;高效的时间管理已经成为我们工作和生活中不可或缺的一部分。为了实现这一目标&#xff0c;我们经常会借助各种工具和软件来辅助我们完成定时任务。今天&#xff0c;我要为大家介绍一款功能强大、操作简便的定时任务执行软件——《定时执行专家》。这款软…

ChromeDriver 122 版本为例 国内下载地址及安装教程

ChromeDriver 国内下载地址 https://chromedriver.com/download 靠谱 千千万万别下载错了 先确认 Chrome 浏览器版本 以 win64 版本为例 那我们下载这一个啊&#xff0c;不要下载错了 下载地址贴在这哈 https://storage.googleapis.com/chrome-for-testing-public/122.0.…

差分----外部执行

概念&#xff1a; 统计学中的差分是指离散函数后的后一项减去前一项的差&#xff1b; 一维数据 输入一个长度为n的整数序列。 接下来输入m个操作&#xff0c;每个操作包含三个整数l, r, c&#xff0c;表示将序列中[l, r]之间的每个数加上c。 分析&#xff1a; 对l位置上的…

用miniconda建立PyTorch、Keras、TensorFlow三个环境

一、配置清华镜像conda源 由于网络问题&#xff0c;直接使用conda默认的源下载包可能会非常慢。为了解决这个问题&#xff0c;可以配置国内镜像源来加速包的下载。清华大学TUNA协会提供了一个常用的conda镜像源。下面是如何配置清华镜像源的步骤&#xff1a; 1. 配置清华conda…

Day37:安全开发-JavaEE应用JNDI注入RMI服务LDAP服务JDK绕过调用链类

目录 JNDI注入-RMI&LDAP服务 JNDI远程调用-JNDI-Injection JNDI远程调用-marshalsec JNDI-Injection & marshalsec 实现原理 JNDI注入-FastJson漏洞结合 JNDI注入-JDK高版本注入绕过 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文…

如何理解Redis中的缓存雪崩,缓存穿透,缓存击穿?

目录 一、缓存雪崩 1.1 解决缓存雪崩问题 二、缓存穿透 2.1 解决缓存穿透 三、缓存击穿 3.1 解决缓存击穿 3.2 如何保证数据一致性问题&#xff1f; 一、缓存雪崩 缓存雪崩是指短时间内&#xff0c;有大量缓存同时过期&#xff0c;导致大量的请求直接查询数据库&#xf…

idea:忽略不要搜索unpackage文件夹

开发vue时搜索关键字&#xff0c;会搜索到编译后的文件&#xff0c;如unpackage。&#xff08;注意这个是idea工具&#xff0c;和Git忽略是有区别的&#xff09; File->Settings->Editor->File Types

Ubuntu 安装腾讯会议

1.官网下载 进入腾讯会议下载官网下载腾讯会议Linux客户端 选择x86_64格式安装包下载 若不知道自己的系统架构,输入 uname -a 在命令行结果中查看系统架构信息 2.终端命令安装 cd {你的下载路径} sudo dpkg -i TencentMeeting_0300000000_3.19.0.401_x86_64_default.publi…

2024-03-11,12(HTML,CSS)

1.HTML的作用就是在浏览器摆放内容。 2.HTML基本骨架 head&#xff1a;网页头部&#xff0c;是给浏览器看的代码&#xff0c;例如CSS body&#xff1a;网页主体&#xff0c;是给用户看的代码&#xff0c;例如图片&#xff0c;文字。 title&#xff1a;网页标题 3.标签的两种…

Midjourney绘图欣赏系列(十一)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

超简单的html+css魔幻霓虹灯文字特效

超简单的htmlcss魔幻霓虹灯文字特效&#xff0c; 效果如下 动态效果&#xff0c;自行查看&#xff0c;创建一个空白的html文件&#xff0c;将下面代码拷贝进去&#xff0c;双击html文件运行即可 <!DOCTYPE html> <html lang"zh-CN"> <head><…

基于Redis实现分布式锁、限流操作(基于SpringBoot)的实现

基于Redis实现分布式锁、限流操作——基于SpringBoot实现 本文总结了一种利用Redis实现分布式锁、限流的较优雅的实现方式本文原理介绍较为通俗&#xff0c;希望能帮到有需要的人本文的demo地址&#xff1a;https://gitee.com/rederxu/lock_distributed.git 一、本文基本实现…

测试用例的设计(2)

目录 1.前言 2.正交排列(正交表) 2.1什么是正交表 2.2正交表的例子 2.3正交表的两个重要性质 3.如何构造一个正交表 3.1下载工具 3.1构造前提 4.场景设计法 5.错误猜测法 1.前言 我们在前面的文章里讲了测试用例的几种设计方法,分别是等价类发,把测试例子划分成不同的类…

第九节:揭开交互的秘密:如何制作原型图

交互设计与用户体验(上) 一、交互、原型的概念及关系 1、什么是交互? 交互(interaction)是指用户与产品之间的互动,即用户输入(input),产品对应给出反馈(Feedback)或输出(Output)的过程。简单可以理解为【交流和互动】。我们把任何两个系统之间的交互都可以看做【对…

P4513 小白逛公园 习题笔记(线段树维护区间最大连续子段和)

传送门https://www.luogu.com.cn/problem/P4513本文参考了董晓老师的博客 这道题着实想了很长时间&#xff08;新手&#xff09;&#xff0c;只能想到一个O&#xff08;mn&#xff09;的dp普通写法&#xff0c;那么遇上区间修改问题改怎么操作呢。答案很明显&#xff0c;线段树…

JVM垃圾收集算法

标记清除算法 1先把垃圾对象标记出来 2然后再进行挨个清除 缺点&#xff1a; 1.清除后的内存空间是不连续的碎片&#xff0c; 2.效率也不高&#xff08;相对于复制算法&#xff0c;复制算法是一次性清除&#xff0c;标记清除是挨个清除&#xff09; 复制算法&#xff08;适…