在函数内部定义类,那么定义的类的作用域就相对较小,可以叫做局域的内部类,类比临时变量,那么我们在外面定义的类就可以叫做'全局变量',这个在后面的命名空间也会有相关涉及。
#include<iostream>
int main()
{
class Test{
int a=1;
int b=2;
public:
void show()
{
std::cout << a << ":" << b << std::endl;
}
};
Test test;
test.show();
return 0;
}
这样定义的类是可以运行的。那么我们在一个临时作用域内定义呢?
就会出现如上结果,显示是未定义的,那么也就是说,我们一般定义是声明并且定义。我们也可以单纯的声明一个类。即
class test;
单纯的声明这种在什么地方会用到呢?举一些情况吧,后面的友元类,两个类互相包含了对方的指针或者对象成员(但是不能互相包含对象,为什么不能包含呢?因为这样就会形成一个环。这种是错误的。)
那么讲一讲头文件和宏定义变量
#define identifier replacement-list(optional) (1)
#define identifier( parameters ) replacement-list(optional) (2)
#define identifier( parameters, ... ) replacement-list(optional) (3) (since C++11)
#define identifier( ... ) replacement-list(optional) (4) (since C++11)
#undef identifier
五种define
第一种:变量式声明定义,如果没有就可以理解为定义了一个没有给初始值的变量。没有就相当于空替换。
第二种:函数式声明定义,如果给了后面的替换值就替换,没有就相同于空替换
第三种:函数式定义,可变量参数,如果后面定义替换之就替换,没有就相当于空替换。
第四种:函数式,可变。可选替换。
undef相当于删除前面的声明定义,也就是说在这个之前,宏定义有效,否则,无效。
#define F(...) f(0 __VA_OPT__(,) __VA_ARGS__)
#define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__)
#define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ })
F(a, b, c) // replaced by f(0, a, b, c)
F() // replaced by f(0)
G(a, b, c) // replaced by f(0, a, b, c)
G(a, ) // replaced by f(0, a)
G(a) // replaced by f(0, a)
SDEF(foo); // replaced by S foo;
SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 };
#define showlist(...) puts(#__VA_ARGS__)
showlist(); // expands to puts("")
showlist(1, "x", int); // expands to puts("1, \"x\", int")
##这种会一直匹配后面的,直到不是定义字符位置。这种常常用来定义一类变量,开发的时候用到过。那么讲一讲头文件和宏定义。那么,这里也要引入一些宏定义。
#if expression
#ifdef identifier
#ifndef identifier
#elif expression
#else
#endif
第一种是条件判断,即真值判断,如if 1,这个是混合型,可以参杂表达式和宏定义。
第二种是判断宏是否存在。这两种一个是代码型,一个是宏类型。
第三种是判断宏是否不存在。
第四种是elif条件分支
第五种是else条件分支。
第六种是if的终止。
那么进入正题头文件在复杂的情况中会被多次包含,即include,那么如果多次引入,就会造成重复定义,重复声明,这个往往会造成未知的编译错误。
我们通常会以文件名_H_的形式进行一段简短的定义。如下。
//test.h
#ifndf _TEST_H_
#define _TEST_H_
void show()
{
}
#endif
这个代码就是,一个test.h如果没有定义这个头文件,即没有引入过这个头文件,就定义,然后执行下面的,如果定义了,就不包含了。这样就避免重复定义,特别是重复声明。