이 페이지에서

QSharedDataPointer Class

template <typename T> class QSharedDataPointer

QSharedDataPointer 클래스는 암시적으로 공유되는 객체에 대한 포인터를 나타냅니다. 더 보기...

헤더: #include <QSharedDataPointer>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
상속: QSharedDataPointerBase

참고: 이 클래스의 모든 함수는 재진입 가능합니다.

QSharedDataPointer 비교

범주비교 가능한 유형
strongQSharedDataPointer
strongT* 및 std::nullptr_t.

공개 유형

공개 함수

QSharedDataPointer()
QSharedDataPointer(T *data)
(since 6.0) QSharedDataPointer(T *data, QAdoptSharedDataTag)
QSharedDataPointer(const QSharedDataPointer<T> &o)
QSharedDataPointer(QSharedDataPointer<T> &&o)
~QSharedDataPointer()
const T *constData() const
T *data()
const T *data() const
void detach()
(since 6.0) T *get()
(since 6.0) const T *get() const
(since 6.0) void reset(T *ptr = nullptr)
void swap(QSharedDataPointer<T> &other)
(since 6.0) T *take()
operator T *()
operator const T *() const
bool operator!() const
T &operator*()
const T &operator*() const
T *operator->()
const T *operator->() const
QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other)
QSharedDataPointer<T> &operator=(T *o)
QSharedDataPointer<T> &operator=(const QSharedDataPointer<T> &o)

보호된 함수

T *clone()
bool operator!=(T *const &lhs, const QSharedDataPointer<T> &rhs)
bool operator!=(const QSharedDataPointer<T> &lhs, const QSharedDataPointer<T> &rhs)
bool operator==(T *const &lhs, const QSharedDataPointer<T> &rhs)
bool operator==(const QSharedDataPointer<T> &lhs, const QSharedDataPointer<T> &rhs)

상세 설명

QSharedDataPointer는 템플릿 매개변수 T 가 QSharedData 에서 파생된 공유 데이터 클래스의 유형을 지정하는 템플릿 클래스입니다.

QSharedDataPointer<T>를 사용하면 암시적으로 공유되는 사용자 정의 클래스를 쉽게 작성할 수 있습니다. QSharedDataPointer는 스레드 안전 참조 카운팅을 구현하여, 재진입 가능한 클래스에 QSharedDataPointer를 추가하더라도 해당 클래스가 재진입 불가능해지지 않도록 보장합니다.

암시적 공유는 포인터의 속도와 메모리 효율성을 클래스의 사용 편의성과 결합하기 위해 많은 Qt 클래스에서 사용됩니다. 자세한 내용은 ‘공유 클래스’ 페이지를 참조하십시오.

Employee 클래스를 암시적으로 공유되도록 만들고 싶다고 가정해 보겠습니다. 절차는 다음과 같습니다.

  • Employee 클래스를 정의할 때 QSharedDataPointer<EmployeeData> 유형의 데이터 멤버를 하나 포함하도록 합니다.
  • ` QSharedData `에서 파생된 ` EmployeeData ` 클래스를 정의하여, 일반적으로 ` Employee ` 클래스에 포함시켰을 모든 데이터 멤버를 포함하도록 합니다.

이를 실제로 보여주기 위해, 암시적으로 공유되는 ` Employee ` 클래스의 소스 코드를 살펴보겠습니다. 헤더 파일에서 ` Employee `과 ` EmployeeData` 두 클래스를 정의합니다.

#include <QSharedData>
#include <QSharedDataPointer>
#include <QString>

class EmployeeData : public QSharedData
{
public:
    EmployeeData() : id(-1) {}
    EmployeeData(const EmployeeData &other)
        : QSharedData(other), id(other.id), name(other.name) {}
    ~EmployeeData() = default;

    int id;
    QString name;
};

class Employee
{
public:
    Employee() { d = new EmployeeData; }
    Employee(int id, const QString &name) {
        d = new EmployeeData;
        setId(id);
        setName(name);
    }
    Employee(const Employee &other) = default;
    Employee &operator=(const Employee &other) = default;

    Employee(Employee &&other) = default;
    Employee &operator=(Employee &&other) = default;

    ~Employee() = default;

    void setId(int id) { d->id = id; }
    void setName(const QString &name) { d->name = name; }

    int id() const { return d->id; }
    QString name() const { return d->name; }

private:
    QSharedDataPointer<EmployeeData> d;
};

Employee 클래스에서, QSharedDataPointer<EmployeeData> 타입의 d 포인터라는 단일 데이터 멤버에 주목하십시오. 직원 데이터에 대한 모든 액세스는 d 포인터의 operator->() 를 통해 이루어져야 합니다. 쓰기 액세스의 경우, operator->() 는 자동으로 detach()를 호출하며, 이 함수는 공유 데이터 객체의 참조 횟수가 1보다 클 때 해당 객체의 복사본을 생성합니다. 이를 통해 한 Employee 객체에 대한 쓰기 작업이 동일한 EmployeeData 객체를 공유하는 다른 Employee 객체에는 영향을 미치지 않도록 보장합니다.

EmployeeData 클래스는 QSharedData 을 상속받으며, 이 클래스는 내부적으로 참조 카운터를 제공합니다. EmployeeData 에는 기본 생성자, 복사 생성자 및 소멸자가 있습니다. 일반적으로 암시적으로 공유되는 클래스의 데이터 클래스에서는 이러한 함수들에 대한 간단한 구현만으로도 충분합니다.

Employee 클래스에 대한 두 개의 생성자를 구현하는 것도 간단합니다. 두 생성자 모두 EmployeeData 의 새 인스턴스를 생성하여 이를 d 포인터에 할당합니다.

Employee() { d = new EmployeeData; }

Employee(int id, const QString &name) {
    d = new EmployeeData;
    setId(id);
    setName(name);
}

Employee 클래스에는 이 경우 엄밀히 말해 필수적이지는 않지만, 사소한 복사 생성자도 정의되어 있다는 점에 유의하십시오.

Employee(const Employee &other) = default;
Employee &operator=(const Employee &other) = default;

Employee(Employee &&other) = default;
Employee &operator=(Employee &&other) = default;

~Employee() = default;

여기서는 복사 생성자가 엄밀히 말해 필수적이지 않습니다. 왜냐하면 ` EmployeeData ` 클래스가 ` Employee ` 클래스(employee.h)와 같은 파일에 포함되어 있기 때문입니다. 그러나 ` QSharedData `의 비공개 하위 클래스를 `QSharedDataPointer`를 포함하는 공개 클래스와 같은 파일에 포함시키는 것은 일반적인 방식이 아닙니다. 일반적으로 QSharedData 의 비공개 하위 클래스는 공개 파일에 포함되지 않는 별도의 파일에 배치하여 사용자에게 노출되지 않도록 하는 것이 원칙입니다. 이 경우, 일반적으로 EmployeeData 클래스를 employee.h 에 포함되지 않는 별도의 파일에 배치합니다. 대신, employee.h 에서 비공개 하위 클래스 EmployeeData 을 다음과 같이 사전 선언하면 됩니다:

class EmployeeData;

만약 여기서 그런 방식으로 처리했다면, 표시된 복사 생성자가 필수적으로 필요했을 것입니다. 복사 생성자는 사소한 것이므로, 차라리 항상 포함시켜 두는 편이 낫습니다.

내부적으로 QSharedDataPointer는 Employee 객체가 복사되거나, 할당되거나, 매개변수로 전달될 때마다 참조 카운트를 자동으로 증가시킵니다. 또한 Employee 객체가 삭제되거나 범위 밖으로 나갔을 때마다 참조 카운트를 감소시킵니다. 참조 카운트가 0에 도달하면 공유된 EmployeeData 객체는 자동으로 삭제됩니다.

Employee 의 non-const 멤버 함수 내에서 d 포인터가 역참조될 때마다, QSharedDataPointer는 함수가 데이터의 자체 복사본을 대상으로 작동하도록 보장하기 위해 자동으로 detach()를 호출합니다.

void setId(int id) { d->id = id; }

void setName(const QString &name) { d->name = name; }

d 포인터가 여러 번 해참조되어 detach()가 멤버 함수 내에서 한 번 이상 호출되는 경우, detach()는 첫 번째 호출 시에만 공유 데이터의 사본을 생성합니다(생성되는 경우). 이는 detach()가 두 번째 및 그 이후로 호출될 때 참조 카운트가 다시 1이 되기 때문입니다.

하지만 직원 ID와 이름을 매개변수로 받는 두 번째 Employee 생성자에서는 setId()와 setName()이 모두 호출되지만, 새로 생성된 EmployeeData 객체의 참조 횟수가 방금 1로 설정되었기 때문에 ‘쓰기 시 복사(copy on write)’가 발생하지 않는다는 점에 유의하십시오.

Employee 의 const 멤버 함수에서 d 포인터 의 참조를 해제하더라도 detach()이 호출되지는 않습니다.

int id() const { return d->id; }

QString name() const { return d->name; }

Employee 클래스의 경우 복사 생성자나 할당 연산자를 구현할 필요가 없다는 점에 유의하십시오. C++ 컴파일러가 제공하는 복사 생성자와 할당 연산자가 필요한 멤버별 얕은 복사를 수행하기 때문입니다. 복사해야 할 유일한 멤버는 d 포인터이며, 이는 QSharedDataPointer입니다. d 포인터의 operator=() 는 공유된 EmployeeData 객체의 참조 횟수를 증가시킬 뿐입니다.

암시적 공유 대 명시적 공유

Employee 클래스의 경우 암시적 공유가 적합하지 않을 수 있습니다. 암시적으로 공유되는 Employee 클래스의 인스턴스 두 개를 생성하는 간단한 예제를 살펴보겠습니다.

#include "employee.h"

int main()
{
    Employee e1(1001, "Albrecht Durer");
    Employee e2 = e1;
    e1.setName("Hans Holbein");
}

두 번째 직원 e2가 생성되고 e1이 e2에 할당된 후, e1 와 e2 는 모두 직원 번호 1001인 알브레히트 뒤러(Albrecht Durer)를 가리킵니다. 두 Employee 객체는 모두 참조 카운트가 2인 EmployeeData 의 동일한 인스턴스를 가리킵니다. 그 후 e1.setName("Hans Holbein") 가 호출되어 직원의 이름을 변경하려고 하지만, 참조 카운트가 1보다 크기 때문에 이름이 변경되기 전에 ‘쓰기 시 복사(copy-on-write )’가 수행됩니다. 이제 e1 와 e2 는 서로 다른 EmployeeData 객체를 가리킵니다. 이름은 다르지만 둘 다 ID가 1001이며, 이는 아마도 의도한 바가 아닐 것입니다. 물론, 정말로 두 번째 고유한 직원을 생성하려는 목적이라면 e1.setId(1002) 을 그대로 진행해도 되지만, 단순히 모든 곳에서 직원의 이름을 변경하려는 것이라면, 암시적 공유 대신 Employee 클래스에서 explicit sharing 를 사용하는 것을 고려해 보세요.

Employee 클래스에서 d 포인터를 ` QExplicitlySharedDataPointer<EmployeeData>`로 선언하면 명시적 공유가 사용되며, 쓰기 시 복사(copy-on-write) 작업이 자동으로 수행되지 않습니다(즉, 비const 함수에서는 ` detach()`가 호출되지 않습니다). 이 경우, ` e1.setName("Hans Holbein")`을 호출한 후에는 직원의 이름이 변경되었지만, `e1`과 `e2`는 여전히 ` EmployeeData`의 동일한 인스턴스를 가리키므로 ID가 1001인 직원은 단 한 명뿐입니다.

멤버 함수 문서에서 d 포인터는 항상 공유 데이터 객체를 가리키는 내부 포인터를 가리킵니다.

Qt 컨테이너에서 사용하기 위한 성능 최적화

위의 ` Employee ` 클래스와 유사하며, 유일한 멤버로 `QSharedDataPointer` 또는 ` QExplicitlySharedDataPointer `를 사용하는 경우, 암시적으로 공유되는 클래스를 ` Q_DECLARE_TYPEINFO()` 매크로를 사용하여 이동 가능한 유형으로 표시하는 것을 고려해야 합니다. 이렇게 하면 Qt의 컨테이너 클래스를 사용할 때 성능과 메모리 효율성을 향상시킬 수 있습니다.

QSharedData, QExplicitlySharedDataPointer, QScopedPointer 및 QSharedPointer도 참조하십시오 .

멤버 유형 문서

QSharedDataPointer::Type

이것은 공유 데이터 객체의 유형입니다. d 포인터는 이 유형의 객체를 가리킵니다.

멤버 함수 설명

[noexcept] QSharedDataPointer::QSharedDataPointer()

nullptr 를 d 포인터로 사용하여 초기화된 QSharedDataPointer 객체를 생성합니다.

[explicit noexcept] QSharedDataPointer::QSharedDataPointer(T *data)

d 포인터가 ` data `로 설정된 `QSharedDataPointer`를 생성하고, ` data`의 참조 횟수를 1 증가시킵니다.

[noexcept, since 6.0] QSharedDataPointer::QSharedDataPointer(T *data, QAdoptSharedDataTag)

d 포인터가 ` data`로 설정된 `QSharedDataPointer`를 생성합니다. ` data`의 참조 카운터는 증가 하지 않으며, 이는 ` take()`에서 얻은 포인터를 채택하는 데 사용할 수 있습니다.

이 함수는 Qt 6.0에서 도입되었습니다.

take()도 참조하십시오 .

[noexcept] QSharedDataPointer::QSharedDataPointer(const QSharedDataPointer<T> &o)

이 객체의 d 포인터를 o 에 있는 d 포인터로 설정하고, 공유 데이터 객체의 참조 횟수를 1 증가시킵니다.

[noexcept] QSharedDataPointer::QSharedDataPointer(QSharedDataPointer<T> &&o)

QSharedDataPointer 인스턴스를 생성하여, 해당 인스턴스가 ` o `가 가리키던 것과 동일한 객체를 가리키게 합니다.

QSharedDataPointer::~QSharedDataPointer()

공유 데이터 객체의 참조 횟수를 1 줄입니다. 참조 횟수가 0이 되면 공유 데이터 객체가 삭제됩니다. 그러면 이 객체는 소멸됩니다.

[protected] T *QSharedDataPointer::clone()

현재 데이터의 딥 복사본을 생성하여 반환합니다. 이 함수는 참조 카운트가 1보다 클 때 detach()에 의해 호출되어 새로운 복사본을 생성합니다. 이 함수는 new 연산자를 사용하며, T 유형의 복사 생성자를 호출합니다.

이 함수는 사용자가 자체 유형에 대해 “가상 복사 생성자”를 지원할 수 있도록 제공됩니다. 이를 위해서는 아래 예제와 같이 자체 유형에 대해 이 함수의 템플릿 특화형을 선언해야 합니다.

template<>
EmployeeData *QSharedDataPointer<EmployeeData>::clone()
{
    return d->clone();
}

위의 예제에서 clone() 함수에 대한 템플릿 특화 버전은 EmployeeData::clone() 가상 함수를 호출합니다. EmployeeData에서 파생된 클래스는 해당 함수를 재정의하여 적절한 다형성 타입을 반환할 수 있습니다.

[noexcept] const T *QSharedDataPointer::constData() const

공유 데이터 객체에 대한 const 포인터를 반환합니다. 이 함수는 detach()을 호 출하지 않습니다.

data()도 참조하십시오 .

T *QSharedDataPointer::data()

공유 데이터 객체에 대한 포인터를 반환합니다. 이 함수는 detach()를 호출합니다.

constData()도 참조하십시오 .

[noexcept] const T *QSharedDataPointer::data() const

공유 데이터 객체에 대한 포인터를 반환합니다. 이 함수는 ` detach()`를 호출하지 않습니다.

void QSharedDataPointer::detach()

공유 데이터 객체의 참조 횟수가 1보다 크면, 이 함수는 공유 데이터 객체의 깊은 복사본을 생성하고 this의 d 포인터를 해당 복사본으로 설정합니다.

이 함수는 ` QSharedDataPointer `의 비const 멤버 함수에서 '쓰기 시 복사(copy on write)'가 필요한 경우 자동으로 호출됩니다. 직접 호출할 필요는 없습니다.

[since 6.0] T *QSharedDataPointer::get()

data()와 동일합니다. 이 함수는 STL 호환성을 위해 제공됩니다.

이 함수는 Qt 6.0에서 도입되었습니다.

[noexcept, since 6.0] const T *QSharedDataPointer::get() const

data()와 동일합니다. 이 함수는 STL 호환성을 위해 제공됩니다.

이 함수는 Qt 6.0에서 도입되었습니다.

[noexcept, since 6.0] void QSharedDataPointer::reset(T *ptr = nullptr)

ptr 가 nullptr 가 아닌 경우, 이 객체의 d 포인터를 ptr 로 설정하고 ptr 의 참조 횟수를 1 증가시킵니다. 기존 공유 데이터 객체의 참조 횟수는 1 감소하며, 참조 횟수가 0이 되면 해당 객체는 삭제됩니다.

이 함수는 Qt 6.0에서 도입되었습니다.

[noexcept] void QSharedDataPointer::swap(QSharedDataPointer<T> &other)

이 공유 데이터 포인터를 ` other`와 교환합니다. 이 작업은 매우 빠르며 절대 실패하지 않습니다.

[noexcept, since 6.0] T *QSharedDataPointer::take()

공유 객체에 대한 포인터를 반환하고, ` this`를 ` nullptr`로 재설정합니다. (즉, 이 함수는 `this `의 `d` 포인터를 ` nullptr`로 설정합니다.)

참고: 반환된 객체의 참조횟수는 감소되지 않습니다. 이 함수는 QAdoptSharedDataTag 태그 객체를 인수로 받는 생성자와 함께 사용하여, 원자적 연산을 거치지 않고 공유 데이터 객체를 전달할 수 있습니다.

이 함수는 Qt 6.0에서 도입되었습니다.

QSharedDataPointer::operator T *()

공유 데이터 객체에 대한 포인터를 반환합니다. 이 함수는 detach()를 호출합니다.

data() 및 constData()도 참조하십시오 .

[noexcept] QSharedDataPointer::operator const T *() const

공유 데이터 객체에 대한 포인터를 반환합니다. 이 함수는 ` detach()`을 호출하지 않습니다.

[noexcept] bool QSharedDataPointer::operator!() const

이 객체의 d 포인터가 ` nullptr`인 경우 ` true `를 반환합니다.

T &QSharedDataPointer::operator*()

공유 데이터 객체의 멤버에 대한 액세스를 제공합니다. 이 함수는 ` detach()`를 호출합니다.

const T &QSharedDataPointer::operator*() const

공유 데이터 객체의 멤버에 대한 const 접근을 제공합니다. 이 함수는 ` detach()`를 호출하지 않습니다.

T *QSharedDataPointer::operator->()

공유 데이터 객체의 멤버에 대한 액세스를 제공합니다. 이 함수는 ` detach()`를 호출합니다.

[noexcept] const T *QSharedDataPointer::operator->() const

공유 데이터 객체의 멤버에 대한 const 액세스를 제공합니다. 이 함수는 ` detach()`를 호출하지 않습니다.

[noexcept] QSharedDataPointer<T> &QSharedDataPointer::operator=(QSharedDataPointer<T> &&other)

other 를 이 QSharedDataPointer 인스턴스에 할당합니다.

[noexcept] QSharedDataPointer<T> &QSharedDataPointer::operator=(T *o)

이 객체의 d 포인터를 o 로 설정하고, o 의 참조 횟수를 1 증가시킵니다. 이 객체의 기존 공유 데이터 객체의 참조 횟수는 1 감소합니다. 기존 공유 데이터 객체의 참조 횟수가 0이 되면, 해당 객체는 삭제됩니다.

[noexcept] QSharedDataPointer<T> &QSharedDataPointer::operator=(const QSharedDataPointer<T> &o)

이 객체의 d 포인터를 ` o `의 d 포인터로 설정하고, 공유 데이터 객체의 참조 횟수를 1 증가시킵니다. 이 객체의 기존 공유 데이터 객체의 참조 횟수는 1 감소합니다. 기존 공유 데이터 객체의 참조 횟수가 0이 되면, 해당 객체는 삭제됩니다.

관련 비멤버 변수

[noexcept] bool operator!=(T *const &lhs, const QSharedDataPointer<T> &rhs)

rhs 의 d 포인터가 lhs 가 아닐 경우, true 를 반환합니다. d 포인터. 이 함수는 detach()를 호출하지 않습니다.

[noexcept] bool operator!=(const QSharedDataPointer<T> &lhs, const QSharedDataPointer<T> &rhs)

lhs 와 rhs 가 동일한 d 포인터를 가리키지 않는 경우, true 를 반환합니다. 이 함수는 detach()를 호출하지 않습니다.

[noexcept] bool operator==(T *const &lhs, const QSharedDataPointer<T> &rhs)

rhs 의 d 포인터가 lhs 인 경우 true 를 반환합니다. 이 함수는 detach()를 호출하지 않습니다.

[noexcept] bool operator==(const QSharedDataPointer<T> &lhs, const QSharedDataPointer<T> &rhs)

lhs 와 rhs 가 동일한 d 포인터를 가리키는 경우, true 를 반환합니다. 이 함수는 detach()를 호출하지 않습니다.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.