우선, 헤더 파일 없이 하나의 파일 안에 클래스 정의와 사용 예시를 작성해보겠습니다.
#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) {
// 이 생성자는 설정값을 직접 사용하는 경우
}