우선, 헤더 파일 없이 하나의 파일 안에 클래스 정의와 사용 예시를 작성해보겠습니다.
#include <iostream>
#include <string>
// 클래스 정의
class Person {
private:
    // 멤버 변수
    std::string name;
    int age;
public:
    // 생성자 (초기화 리스트 사용하지 않은 버전)
    Person(std::string nameInput, int ageInput) {
        name = nameInput;
        age = ageInput;
    }
    // 멤버 함수
    void introduce() {
        std::cout << "Hello, my name is " << name << " and I am " << age << " years old." << std::endl;
    }
    // 나이를 증가시키는 함수
    void increaseAge() {
        age++;
    }
};
int main() {
    // 클래스 객체 생성 및 사용
    Person person1("Alice", 25);
    person1.introduce();  // 출력: Hello, my name is Alice and I am 25 years old.
    
    person1.increaseAge();
    person1.introduce();  // 출력: Hello, my name is Alice and I am 26 years old.
    
    return 0;
}
초기화 리스트를 사용하면 생성자 내부에서 멤버 변수를 더 효율적으로 초기화할 수 있습니다.
#include <iostream>
#include <string>
// 클래스 정의
class Person {
private:
    std::string name;
    int age;
public:
    // 생성자 (초기화 리스트 사용한 버전)
    Person(std::string nameInput, int ageInput) : name(nameInput), age(ageInput) {
        // 빈 블록: 초기화 리스트로 이미 초기화됨
    }
    void introduce() {
        std::cout << "Hello, my name is " << name << " and I am " << age << " years old." << std::endl;
    }
    void increaseAge() {
        age++;
    }
};
int main() {
    Person person2("Bob", 30);
    person2.introduce();  // 출력: Hello, my name is Bob and I am 30 years old.
    return 0;
}
name(nameInput), age(ageInput) 형태로 초기화 리스트를 사용헤더 파일을 사용하여 클래스 정의와 구현을 분리하는 방식은 더 큰 프로젝트에서 사용하기 적합
Person.h (헤더 파일)#ifndef PERSON_H
#define PERSON_H
#include <string>
class Person {
private:
    std::string name;
    int age;
public:
    // 생성자
    Person(std::string nameInput, int ageInput);
    
    // 멤버 함수 선언
    void introduce();
    void increaseAge();
};
#endif
Person.cpp (구현 파일)#include "Person.h"
#include <iostream>
// 생성자 정의 (초기화 리스트 사용)
Person::Person(std::string nameInput, int ageInput) : name(nameInput), age(ageInput) {
    // 초기화는 이미 리스트로 완료됨
}
// 멤버 함수 정의
void Person::introduce() {
    std::cout << "Hello, my name is " << name << " and I am " << age << " years old." << std::endl;
}
void Person::increaseAge() {
    age++;
}
main.cpp (메인 파일)#include "Person.h"
int main() {
    Person person3("Charlie", 40);
    person3.introduce();  // 출력: Hello, my name is Charlie and I am 40 years old.
    person3.increaseAge();
    person3.introduce();  // 출력: Hello, my name is Charlie and I am 41 years old.
    return 0;
}
Person.h 파일에는 클래스의 정의와 멤버 함수 선언만 포함되어 있습니다.Person.cpp 파일은 실제로 함수가 어떻게 동작하는지에 대한 구현이 들어가 있습니다.main.cpp 파일에서는 #include "Person.h"를 통해 Person 클래스를 사용C++에서 public, private, protected는 접근 지정자(Access Specifiers)로, 클래스의 멤버(변수 및 함수)에 대해 외부에서 접근할 수 있는 범위를 결정합니다. 각각의 접근 지정자가 하는 역할을 설명하겠습니다.
public (공개 접근)public으로 선언된 멤버는 클래스 외부에서도 접근할 수 있습니다.. 연산자를 통해 직접 해당 멤버 변수나 함수에 접근할 수 있습니다.class Example {
public:
    int publicVar;  // public 멤버 변수
    void publicMethod() {  // public 멤버 함수
        std::cout << "This is a public method." << std::endl;
    }
};
int main() {
    Example obj;
    obj.publicVar = 10;  // 클래스 외부에서 접근 가능
    obj.publicMethod();  // 클래스 외부에서 호출 가능
}
publicVar와 publicMethod()는 클래스 외부에서도 자유롭게 접근할 수 있습니다.private (비공개 접근)private로 선언된 멤버는 클래스 외부에서는 접근할 수 없습니다.public 메서드를 통해 접근하는 방법을 사용해야 합니다.class Example {
private:
    int privateVar;  // private 멤버 변수
    void privateMethod() {  // private 멤버 함수
        std::cout << "This is a private method." << std::endl;
    }
public:
    void setPrivateVar(int value) {  // public 멤버 함수로 private 멤버에 접근
        privateVar = value;
    }
    void showPrivateMethod() {  // public 멤버 함수로 private 메서드 호출
        privateMethod();
    }
};
int main() {
    Example obj;
    // obj.privateVar = 10;  // 오류: private 멤버는 외부에서 직접 접근 불가능
    obj.setPrivateVar(10);  // public 함수 통해 간접적으로 접근 가능
    obj.showPrivateMethod();  // public 함수 통해 private 메서드 호출 가능
}
privateVar와 privateMethod()는 클래스 외부에서 직접 접근할 수 없습니다.setPrivateVar()와 showPrivateMethod() 같은 public 메서드를 통해 간접적으로 접근할 수 있습니다.protected (보호된 접근)protected로 선언된 멤버는 클래스 외부에서는 접근할 수 없지만, 파생 클래스(상속받은 클래스)에서는 접근할 수 있습니다.private과 달리 상속받은 클래스에서 접근이 허용되지만, 외부에서는 여전히 접근할 수 없습니다.class Base {
protected:
    int protectedVar;  // protected 멤버 변수
public:
    void setProtectedVar(int value) {
        protectedVar = value;
    }
};
class Derived : public Base {
public:
    void showProtectedVar() {
        std::cout << "Protected Var: " << protectedVar << std::endl;
        // 파생 클래스에서는 protected 멤버에 접근 가능
    }
};
int main() {
    Derived obj;
    obj.setProtectedVar(20);
    obj.showProtectedVar();  // 출력: Protected Var: 20
}
protectedVar는 Derived 클래스에서 접근할 수 있지만, main() 함수처럼 외부에서는 접근할 수 없습니다.public, private, protected의 차이점 요약:| 접근 지정자 | 클래스 내부 | 파생 클래스(상속) | 외부 (클래스 외부) | 
|---|---|---|---|
| public | O | O | O | 
| protected | O | O | X | 
| private | O | X | X | 
public: 외부에서 객체를 통해 직접 접근해야 하는 멤버에 사용됩니다. (예: 클래스 사용자에게 제공되는 인터페이스)private: 외부에서 접근을 허용하지 않아야 하는 멤버에 사용됩니다. (예: 내부 구현 세부 사항, 보안 관련 데이터)protected: 상속을 통해 파생 클래스에서 접근해야 하지만, 외부에서는 접근이 허용되지 않아야 하는 멤버에 사용됩니다. (예: 상속받은 클래스가 사용할 수 있는 변수나 함수)이를 통해 적절한 캡슐화와 접근 제어를 유지할 수 있습니다.
구체적으로 살펴보면:
헤더 파일에 두 가지 생성자 선언이 있습니다.
TsdfServer(const ros::NodeHandle& nh, const ros::NodeHandle& nh_private);
TsdfServer(const ros::NodeHandle& nh, const ros::NodeHandle& nh_private,
           const TsdfMap::Config& config,
           const TsdfIntegratorBase::Config& integrator_config,
           const MeshIntegratorConfig& mesh_config);
NodeHandle을 매개변수로 받는 생성자입니다.config, integrator_config, mesh_config)을 매개변수로 받습니다..cc 파일에서는 두 생성자의 실제 구현이 제공됩니다.
TsdfServer::TsdfServer(const ros::NodeHandle& nh,
                       const ros::NodeHandle& nh_private)
    : TsdfServer(nh, nh_private, getTsdfMapConfigFromRosParam(nh_private),
                 getTsdfIntegratorConfigFromRosParam(nh_private),
                 getMeshIntegratorConfigFromRosParam(nh_private)) {}
getTsdfMapConfigFromRosParam(), getTsdfIntegratorConfigFromRosParam(), getMeshIntegratorConfigFromRosParam() 함수들을 사용하여, nh_private에서 구성 정보를 가져와 두 번째 생성자를 호출합니다.TsdfServer::TsdfServer(const ros::NodeHandle& nh,
                       const ros::NodeHandle& nh_private,
                       const TsdfMap::Config& config,
                       const TsdfIntegratorBase::Config& integrator_config,
                       const MeshIntegratorConfig& mesh_config) {
    // 이 생성자는 설정값을 직접 사용하는 경우
}