1.1 枚举
linux中文件从一个位置复制到另一个位置:
bash
cp logclass.cpp /home/zymaaacmx/codecpp_project/z8enum/logclass.cpp
如果是整个目录及其目录下的所有文件
bash
cp -r /home/user/old_dir /home/user/new_dirf
复制多个文件到目标目录
bash
cp file1.txt file2.txt /home/user/Documents
注意:
- 如果目标文件或目录已经存在,cp 命令会提示是否覆盖。
- 如果目标位置不存在,cp 命令会自动创建该位置。
- 如果在复制时要保留文件属性(如权限、拥有者、时间戳),可以加上 -p 选项:cp -p source_file target_file。
c
#include <iostream>
enum Example : char
{
A = 5,B = 1,C
};
int main()
{
Example value = B;
if(value == B)
{
std::cout << static_cast<int>(value) << std::endl;
std::cout << static_cast<int>(Example::A) <<std::endl;
}
std::cin.get();
}
需要注意的是,在输出 Example::A
的值时,也需要使用 **static_cast<int>(Example::A)**
将 **char**
型的枚举值转换为整数进行输出。
c
#include <iostream>
class Log
{
public:
enum Level
{
LeError = 0,LeWarning,LeInfo
};/*const int LogLevelError = 0; const int LogLevelWarning = 1;*/
private:
Level m_LogLevel = LeInfo;//int m_LogLevel;m_代表着这是一个私有的类成 员变量
public:
void SetLevel(Level level)
{
m_LogLevel = level;
}
void Error(const char* message)
{
if (m_LogLevel >= LeError)
std::cout << "[ERROR]:" << message << std::endl;
}
void Warm(const char* message)
{
if (m_LogLevel >= LeWarning)
std::cout << "[WARNING]:" << message << std::endl;
}
void Info(const char* message)
{
if (m_LogLevel >= LeInfo)
std::cout << "[INFO]:" << message << std::endl;
}
};
int main()
{
Log log;
log.SetLevel(Log::LeError);
//log.SetLevel(log.LogLevelWarning);//2是信息或者跟踪,
log.Error("Helo!");
log.Info("Hello!");
log.Warm("Hello!");
std::cin.get();
}
为什么是Log::LeError,而不能是log::LeError
Log::LeError 表示 Log 类的成员 LeError,可以理解为把 LeError 拼在 Log 的后面,表示它是 Log 类的一部分。而 log::LeError 则表示 log 对象的成员 LeError,这是非法的,因为 LeError 并不是一个对象的成员,而是一个类的成员。
结果:

1.2 构造函数(constructor)
构造函数是类中一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类名相同,并且没有返回类型(包括 void),因此它们不能被显式调用 ,而是在创建对象时自动调用。
构造函数有以下几个特点:
- 构造函数在对象创建时自动调用,用于初始化对象的成员变量。
- 构造函数可以有参数,用于传递初始化对象所需的信息。
- 每个类都可以定义一个或多个构造函数,它们之间可以通过参数类型和个数的不同进行重载。
- 如果没有显式定义构造函数,编译器会生成一个默认的无参构造函数(如果没有其他构造函数定义的话)。
- 如果显式定义了构造函数,则默认构造函数将不再被生成。需要注意的是,如果定义了有参构造函数,但仍想要使用默认构造函数,可以通过显式声明一个无参构造函数来实现。
在Linux中对目录进行操作:
-
删除一个空的目录: rmdir 目录名
-
删除一个非空的目录: rm -r 目录名
-
更改目录的名称 mv 原目录名 新目录名
-
注意,如果新目录名已存在,则会将原目录移动到新目录下作为子目录。如果要将目录移动到其他位置并更改名称,可以提供新的完整路径 mv old_dir /path/to/new_dir
#include
class Entity { public: float X,Y;
cvoid Init() { X = 0.0f; Y = 0.0f; } void Print() { std::cout << X << " , " << Y << std::endl; }
};
int main() { Entity e; e.Init(); std::cout << e.X << std::endl; e.Print(); Entity e1; e1.Init(); e1.Print();
std::cin.get(); }
每个类的实例都想取值相同的x,y。 每次都调用Init() 比较麻烦。
c
#include <iostream>
class Entity
{
public:
float X,Y;
//void Init()
Entity()
{
X = 0.0f;
Y = 0.0f;
}
void Print()
{
std::cout << X << " , " << Y << std::endl;
}
};
int main()
{
Entity e;
//e.Init();
std::cout << e.X << std::endl;
e.Print();
Entity e1;
//e1.Init();
e1.Print();
std::cin.get();
}
相同的结果:

可以有很多构造函数,前提是参数不同。类似函数重载。
函数重载(Function Overloading)指的是在同一个作用域内,可以定义多个同名但参数列表不同的函数。通过函数重载,可以使用相同的函数名实现不同的功能。
函数重载的特点:
- 函数名称必须相同。
- 参数列表必须不同,可以通过参数的类型、数量或顺序进行区分。
- 返回类型可以相同也可以不同。
- 函数重载与函数的返回值类型无关。
c
#include <iostream>
class Entity
{
public:
float X,Y;
//void Init()
Entity()
{
// X = 0.0f;
// Y = 0.0f;
}
Entity(float x,float y)
{
X = x;//参数赋值给了成员变量
Y = y;
}
void Print()
{
std::cout << X << " , " << Y << std::endl;
}
};
int main()
{
Entity e(10.0f,5.0f);
//e.Init();
std::cout << e.X << std::endl;
e.Print();
Entity e1;
//e1.Init();
e1.Print();
Entity e2;
e2.Print();
std::cin.get();
}
结果:

注意:::::C++ 中必须初始化,否则会出现不确定的值
也可以通过创建类删除默认的构造函数。
c
#include <iostream>
class Entity
{
public:
float X,Y;
Entity()
{
}
Entity(float x,float y)
{
X = x;//参数赋值给了成员变量
Y = y;
}
void Print()
{
std::cout << X << " , " << Y << std::endl;
}
};
class Log
{
public:
float a,b;
Log() = delete;//默认的构造函数被删除
static void Write(Log& log)
{
std::cout << log.a << " " << log.b << std::endl;
}
};
int main()
{
Log l{1.0f,2.0f};
//Log l;删除了默认构造函数,这意味着无法使用无参数的方式来创建 Log 对象。
Log::Write(l);
Entity e(10.0f,5.0f);
std::cout << e.X << std::endl;
e.Print();
std::cin.get();
}
结果:

注意:
- 删除了默认构造函数,这意味着无法使用无参数的方式来创建 Log 对象。
- 使用列表初始化方式创建对象并初始化成员变量:分别赋值给 Log 对象 l 的成员变量 a 和 b。
还有两种构造函数:赋值构造函数和移动构造函数
赋值构造函数(Copy Constructor)和移动构造函数(Move Constructor)是 C++ 中的特殊构造函数,用于创建对象的副本或进行资源的移动。
1 赋值构造函数: 赋值构造函数被用于通过已存在的对象创建一个新对象。它通常用于以下情况:
定义:
scss
ClassA(const ClassA& other)
{
// 执行必要的操作,将 other 的值赋给当前对象
}
ClassA obj1; // 创建对象 obj1
ClassA obj2(obj1); // 使用赋值构造函数,创建对象 obj2,并将 obj1 的值赋给 obj2
在赋值构造函数中,参数类型为 const ClassA&
,这表示使用常引用来避免不必要的拷贝。赋值构造函数通常会完成深拷贝,即在新对象的构造过程中复制所有成员变量的值。
2 移动构造函数: 移动构造函数用于将资源从一个对象移动到另一个对象,避免不必要的拷贝操作,提高性能。它通常用于以下情况:
scss
ClassA(ClassA&& other)
{
// 执行必要的操作,将 other 的资源移动到当前对象
}
ClassA obj1; // 创建对象 obj1
ClassA obj2(std::move(obj1)); // 使用移动构造函数,创建对象 obj2,并将 obj1 的资源移动到 obj2
在移动构造函数中,参数类型为 ClassA&&
,这表示使用右值引用来接收需要移动的对象。移动构造函数通常会完成资源的转移,比如指针的所有权转移。
需要注意的是,如果一个类定义了移动构造函数,但没有定义赋值构造函数,那么该类只能进行移动操作,无法进行拷贝操作。
总结: 赋值构造函数和移动构造函数都是特殊的构造函数,用于创建对象的副本或进行资源的移动。赋值构造函数用于通过已存在的对象创建一个新对象,而移动构造函数用于将资源从一个对象移动到另一个对象。它们可以显著提高代码的性能和效率。