머리말:
C++는 프로그래머가 전역 변수를 정의하고 사용할 수 있도록 하는 매우 일반적으로 사용되는 프로그래밍 언어입니다. 전역 변수는 프로그램에서 광범위하게 사용되지만 접근이 전역적이기 때문에 몇 가지 잠재적인 문제를 일으킬 수 있습니다. 이 기사에서는 C++ 전역 변수에 대한 계측 기능 향상에 대해 논의하고 몇 가지 가능한 문제와 솔루션에 대해 논의하며 몇 가지 실용적인 예를 제공합니다.
첫째, 전역 변수의 정의와 사용
C++의 전역 변수는 함수 외부에서 정의할 수 있으므로 전역 범위를 제공합니다. 이 경우 전역 변수는 정의된 함수뿐만 아니라 전체 프로그램에서 볼 수 있습니다.
전역 변수는 다음과 같이 정의됩니다.
int global_var = 10;
전역 변수를 정의한 후에는 프로그램 어디에서나 액세스할 수 있습니다. 예를 들어 함수에서 다음을 사용하여 이 전역 변수에 액세스할 수 있습니다.
void foo(){
std::cout << global_var << std::endl;
}
이 예제에서는 전역 변수 global_var에 액세스할 수 있는 함수 foo()를 정의합니다.
둘째, C++ 전역 변수의 문제
전역 변수는 완전히 무해하지 않습니다. 전역 변수에는 전역 범위가 있으므로 모든 코드에서 수정할 수 있습니다. 이로 인해 다음과 같은 몇 가지 잠재적인 문제가 발생할 수 있습니다.
1. 네임스페이스 오염
전역 변수가 정의되면 변수 이름은 전체 프로그램 이름 공간의 일부가 됩니다. 따라서 프로그램에 여러 전역 변수가 존재하면 이름이 중복되어 네임스페이스 오염이 발생할 수 있습니다. 이것은 코드를 유지하기 어렵게 만들 수 있습니다.
네임스페이스 오염 사례 코드:
// 文件1:global_var1.cpp
int global_var = 0;
// 文件2:global_var2.cpp
int global_var = 1;
// main.cpp
#include <iostream>
int main(){
std::cout << global_var << std::endl; // 编译错误:multiple definition of 'global_var'
return 0;
}
이 코드에서는 두 개의 다른 파일(global_var1.cpp 및 global_var2.cpp)에 동일한 이름을 가진 두 개의 전역 변수를 정의합니다. main.cpp에서 이러한 전역 변수에 액세스하려고 시도하지만 동일한 이름을 가진 여러 전역 변수가 있기 때문에 링크 오류가 발생합니다.
2. 프로그램 보안 문제
전역 변수는 프로그램의 어디에서나 액세스할 수 있으므로 일부 보안 문제가 발생할 수 있습니다. 예를 들어 전역 변수가 암호와 같은 민감한 정보를 저장하는 경우 프로그램의 모든 사용자가 해당 정보에 액세스하고 수정할 수 있습니다.
프로그램 보안 문제 사례 코드:
#include <iostream>
#include <string>
// 存储用户密码的全局变量
std::string password = "12345678";
// 函数1:读取密码
void read_password(){
std::string input_password;
std::cout << "请输入密码:" << std::endl;
std::cin >> input_password;
if(input_password == password){
std::cout << "密码正确" << std::endl;
} else{
std::cout << "密码错误" << std::endl;
}
}
// 函数2:修改密码
void change_password(){
std::string new_password;
std::cout << "请输入新密码:" << std::endl;
std::cin >> new_password;
password = new_password;
std::cout << "密码修改成功" << std::endl;
}
// main函数
int main(){
read_password();
change_password();
read_password();
return 0;
}
이 코드에서는 전역 변수(암호)를 사용하여 사용자의 암호를 저장합니다. 비밀번호를 읽고 비밀번호를 변경하는 두 가지 기능(read_password 및 change_password)을 각각 정의합니다. 전역 변수는 프로그램의 어디에서나 액세스할 수 있으므로 이 암호는 어디에서나 읽고 수정할 수 있으므로 보안 위험이 있습니다.
3. 멀티스레딩 문제
전역 변수는 멀티스레딩 문제를 일으킬 수도 있습니다. 여러 스레드가 전역 변수에 동시에 액세스하고 수정하는 경우 경합 상태 및 교착 상태가 발생할 수 있습니다.
멀티스레딩 문제 사례 코드:
#include <iostream>
#include <thread>
// 全局变量
int global_var = 0;
// 线程1:不断增加全局变量
void thread1(){
for(int i = 0; i < 100000; i++){
global_var++;
}
}
// 线程2:不断减少全局变量
void thread2(){
for(int i = 0; i < 100000; i++){
global_var--;
}
}
// main函数
int main(){
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
std::cout << "global_var = " << global_var << std::endl; // 输出:global_var = -4629
return 0;
}
이 코드에서는 전역 변수(global_var)를 각각 계속 증가 및 감소시키는 두 개의 스레드(thread1 및 thread2)를 정의합니다. 두 스레드가 동시에 전역 변수에 액세스하고 수정하기 때문에 경쟁 조건과 교착 상태가 발생할 수 있습니다.
3. C++ 전역 변수 감지 기능 향상
이러한 가능한 문제를 해결하기 위해 다음 측면을 포함하여 몇 가지 향상된 감지 방법을 사용할 수 있습니다.
1. 네임스페이스에 전역 변수 정의
네임스페이스에서 전역 변수를 정의하면 전역 변수가 다른 변수와 동일한 이름을 갖는 것을 방지할 수 있습니다. 예를 들어:
namespace my_namespace{
int global_var = 10;
}
이런 식으로 프로그램 전체에서 my_namespace::global_var
이 전역 변수에 .
2. 변경 불가능한 전역 변수 대신 상수 사용
전역 변수의 값을 수정하지 않으려면 정의할 때 상수를 대신 사용하는 것이 좋습니다. 예를 들어:
const int global_const_var = 10;
이 예제에서는 상수를 사용하여 전역 변수를 정의합니다. 상수이기 때문에 변경할 수 없으므로 코드가 더 안전합니다.
3. 글로벌 변수 대신 로컬 변수 사용
경우에 따라 전역 변수 대신 지역 변수를 사용할 수 있습니다. 변수가 하나의 함수에서만 사용되는 경우 전역 변수를 정의하는 대신 이 함수에서 로컬 변수를 정의할 수 있습니다. 예를 들어:
void foo(){
int local_var = 10;
std::cout << local_var << std::endl;
}
이 예에서는 전역 변수를 정의하는 대신 로컬 변수 local_var를 정의합니다.
4. 캡슐화 메커니즘 사용
전역 변수를 프로그램의 여러 위치에서 사용해야 하는 경우 캡슐화 메커니즘을 사용하는 것이 좋습니다. 캡슐화 메커니즘을 사용하면 전역 변수 및 관련 함수를 클래스에 캡슐화할 수 있습니다. 이 접근 방식은 클래스의 멤버 함수만 전역 변수에 액세스할 수 있도록 합니다. 예를 들어:
class GlobalVar{
public:
static int get_global_var(){
return global_var;
}
private:
static int global_var;
};
int GlobalVar::global_var = 10;
void foo(){
std::cout << GlobalVar::get_global_var() << std::endl;
}
이 예제에서는 정적 멤버 변수 global_var 및 정적 멤버 함수 get_global_var()를 포함하는 GlobalVar 클래스를 정의합니다. 정적 멤버 변수 및 함수를 사용하면 클래스의 멤버 함수만 전역 변수에 액세스할 수 있습니다.
5. 싱글톤 패턴 사용
싱글톤 패턴은 클래스의 인스턴스가 하나만 있도록 하는 디자인 패턴입니다. 프로그램의 여러 위치에서 전역 변수를 사용해야 하고 인스턴스가 하나만 있는지 확인해야 하는 경우 싱글톤 패턴을 사용할 수 있습니다. 예를 들어:
class GlobalVar{
public:
static GlobalVar* instance(){
static GlobalVar gv;
return &gv;
}
int get_global_var(){
return global_var;
}
private:
GlobalVar(){
global_var = 10;
}
int global_var;
};
void foo(){
std::cout << GlobalVar::instance()->get_global_var() << std::endl;
}
이 예제에서는 GlobalVar 클래스를 정의하고 싱글톤 패턴을 사용하여 인스턴스가 하나만 있는지 확인합니다. 생성자에서 전역 변수 global_var를 초기화합니다. 싱글톤 패턴을 사용하여 인스턴스가 하나만 있는지 확인하고 get_global_var() 함수를 사용하여 클래스의 멤버 함수만 전역 변수에 액세스할 수 있도록 합니다.
요약하다:
C++의 전역 변수는 몇 가지 잠재적인 문제를 일으킬 수 있습니다. 이러한 문제를 해결하기 위해 전역 변수를 네임스페이스에 정의하고, 불변 전역 변수 대신 상수를 사용하고, 전역 변수 대신 지역 변수를 사용하고, 캡슐화 메커니즘을 사용하고, 싱글톤 모드를 사용하는 등 향상된 감지 방법을 사용할 수 있습니다 . 위의 계획은 특정 상황에 따라 사용할 수 있습니다.