C++学习4

119 阅读3分钟

1.1 类

类中的属性默认是private,结构体中的属性默认是public;

#include <iostream>
#define LOG(x) std::cout << x << std::endl;
class Player
{
public:
    int x,y;
    int speed;
};

void Move(Player& player,int xa,int ya)
{
   player.x += xa * player.speed;
   player.y += ya * player.speed;
}

int main()
{
   Player player;
   player.speed = 1;
   player.y = 7;
   player.x = 5;
   Move(player,1,-1);
   LOG("x:" << player.x <<std::endl<< "y:" << player.y);
   std::cin.get();
}

#include <iostream>
#define LOG(x) std::cout << x <<std::endl;
class Player
{
public:
    int x,y;
    int speed;
    void Move(int xa,int ya)
    {
       x += xa * speed;
       y += ya * speed;
    }
};
int main()
{
   Player player;
   player.x = 3;
   player.y = 4;
   player.speed = 1;

   player.Move(1,-1);
   LOG("x = " << player.x <<std::endl<< "y = " << player.y);
   std::cin.get();
}

#include <iostream>
#define LOG(x) std::cout << x <<std::endl;
struct Vec2
{
   float x,y;
   void Add(const Vec2& other)
   {
      x += other.x;
      y += other.y;
   }
};
int main()
{
   Vec2 vec;
   vec.x = 2;
   vec.y = 3;
   Vec2 other;
   other.x = 1;
   other.y = 2;

  vec.Add(other);
  LOG(" x " << vec.x << " y " << vec.y);
  std::cin.get();
}

1.2 log 类

#include <iostream>
class Log
{
public:
   const int LogLevelError = 0;
   const int LogLevelWarning = 1;
   const int LogLevelInfo = 2;
private:
   int m_LogLevel;//m_代表着这是一个私有的类成员变量
public:
   void SetLevel(int level)
   {
      m_LogLevel = level;
   }
   void Error(const char* message)
   {
      if (m_LogLevel >= LogLevelError)
         std::cout << "[ERROR]:" << message << std::endl;
   }
   void Warm(const char* message)
   {
      if (m_LogLevel >= LogLevelWarning)
         std::cout << "[WARNING]:" << message << std::endl;
   }
   void Info(const char* message)
   {
      if (m_LogLevel >= LogLevelInfo)
         std::cout << "[INFO]:" << message << std::endl;
   }
};
int main()
{
   Log log;
   log.SetLevel(log.LogLevelError);
   //2//1 log.SetLevel(log.LogLevelWarning);//2是信息或者跟踪,
   log.Error("Helo!");
   log.Info("Hello!");
   log.Warm("Hello!");
   std::cin.get();
}

1:warning = 2,   大于error = 0;大于等于 warning =1;

2:默认 

3:error = 0

1.3 static

1:结构体或者类外面使用的static
2:结构体或者类里面使用的static

?类外面的static ,意味着声明为static的符号,链接只能在内部。意味着它只能对于你定义的翻译单元可见。
定义在类或者结构体中的静态变量,意味着将与类的所有实列共享内存。

创建的每一个类的实例都含有该静态变量,

静态变量只有一个实例

不能定义两个同名的全局变量

两个文件链接在一起的作用:

将两个文件链接在一起有以下几个常见的用途:

1     模块化开发:将程序分成多个文件可以帮助程序员更好地组织和管理代码。每个文件可以专注于特定功能或模块,使得代码更易读、易维护、易扩展。
2       代码复用:将常用的功能或函数定义在一个文件中,然后在其他文件中链接使用这些功能或函数。这样可以避免重复编写相同的代码,提高了代码的可重用性和开发效率。
3      分布式编程:在大型项目中,不同的团队可能会负责开发不同的模块或组件。将各个团队开发的模块链接在一起,可以形成一个完整的系统。这种模块化的设计能够降低协作和集成的难度。
4      库文件和插件:将一组相关的函数、类或数据结构封装为库文件,供其他程序使用。这样,其他程序可以通过链接该库文件来使用其中的功能,实现了代码的共享和功能的扩展。
5          可执行文件生成:链接多个源代码文件后,可以生成一个可执行文件,用于直接运行程序。这个可执行文件可以被用户或其他系统使用,完成特定的任务。

       总的来说,将多个文件链接在一起可以提高代码的组织性、可重用性和可维护性,同时也为构建大型项目和共享代码提供了方便。

怎么链接两个文件

static.cpp

#include <iostream>

int s_Variable = 10;

int main()
{
   std::cout  << s_Variable << std::endl;
   std::cin.get();
}

static1.cpp

#include <iostream>
int s_Variable = 5;
int main()
{
std::cout << s_Variable <<std::endl;
}

1: 首先编译两个目标文件

g++ static.cpp -o static.o

g++ static1.cpp -o static1.o

2: 然后将目标文件链接在一起生成可执行文件

g++ static.o static1.o -o twostatic

3 : 运行可执行文件

./twostatic

出现报错原因就是两个同名的全局变量,下个笔记补充,要超过最大限制了!!!?

全局变量是一种具有静态存储期的变量,它们的存储空间在程序启动时分配,并在整个程序生命周期内保持存在。如果在多个源文件中都定义了同名的全局变量,那么在链接时会出现符号重定义错误。因为编译器无法确定应该使用哪个定义的全局变量,这就会导致程序无法正确链接。

报错如下:

/usr/bin/ld: static1.o:(.data+0x0): multiple definition of `s_Variable'; static.o:(.data+0x0): first defined here
/usr/bin/ld: static1.o: in function `main':
static1.cpp:(.text+0x0): multiple definition of `main'; static.o:static.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

解决办法有两个:

一个文件中定义      int s_Variable = 10;

另一个文件中不再定义   extern int  s_Variable; (全局变量的声明)

两个文件都用  static 定义变量,相当于这个变量只在这个编译单元中使用。(作用相当于private               

static int s_Variable = 10;     
static int s_Variable = 5;

同样可以发散思维,在头文件中则所有的链接文件中,static修饰的变量这两个文件可以同时共享。