【问题标题】:accessing a c++ unique pointer declared in hpp file when set in a cpp file through constructor通过构造函数在 cpp 文件中设置时访问在 hpp 文件中声明的 c++ 唯一指针
【发布时间】:2022-01-24 00:48:15
【问题描述】:

我是一名 c++ 初学者,对于如何从类构造函数设置私有唯一性同时仍设法从其他公共函数访问它有点困惑。我什至应该使用唯一指针开始还是共享指针?

示例:(来自我正在从事的一个项目)

header.hpp

class PixelHandler {
private:
// don't know if this ia legal
 std::unique_ptr<Ppm> ppm;
 std::vector<std::vector<int>> coordList;
 std::unordered_map<std::string, std::string> generatePassList(std::unordered_map<int, int>);
 

public:
 PixelHandler(int sizex, int sizey);
 PixelHandler(std::string picture);
 std::unordered_map<std::string, std::string> retrievePasswordList();
 void setPasswordList(std::string key, std::string password);

};

source.cpp

PixelHandler::PixelHandler(std::string picture)
{
  
   ppm = Ppm(picture.substr(0, -4) + ".ppm");

}

【问题讨论】:

  • 因为它是一个unique_ptr,你需要构造一个它可以实际管理的对象,例如:通过std::make_unique。除此之外我不明白问题是什么,您有一个私人成员,“从其他公共功能访问它”是什么意思?

标签: c++ unique-ptr


【解决方案1】:

也许你应该这样做:

ppm = std::make_unique<Ppm>(picture.substr(0, -4) + ".ppm");

因为您不能将对象(Ppm 类型)分配给指针。您需要将它传递给 std::unique_ptr 的构造函数,以便它可以创建指向该对象的唯一指针。

【讨论】:

  • 或者最好:PixelHandler::PixelHandler(std::string picture) : ppm(std::make_unique&lt;Ppm&gt;(picture.substr(0, -4) + ".ppm")) {}
【解决方案2】:

我什至应该使用唯一指针开头还是共享指针? 而是指针?

在不知道指针的用途的情况下,您无法获知这一点。 PixelHandler 会是唯一访问ppm 的类吗?即使您从PixelHandler 中的不同点访问它,其他访问将如何?例如,其他访问器接收指向ppm 的原始指针是否就足够了(例如对Ppm 的只读操作)?... 使用unique_ptrshared_ptr 之间的决定主要是处理您指向的对象的所有权。

我是 C++ 初学者,对如何设置 来自类构造函数的私有唯一,同时仍设法访问 它来自其他公共功能。

您可以在PixelHandler 的构造函数中初始化Ppm 指针,然后在其他PixelHandler 的方法中使用它。在 PixelHandler 实例被销毁之前,Ppm 实例不会被销毁。

顺便说一句,如果您想从图片路径(例如jpgpng 等)形成Ppm 路径,您可以使用std::filesystem 中的设施(path 和@ 987654339@)。我不认为 substr(0, -4) 在 C++ 中可以作为删除扩展的一种方式。

[Demo]

#include <filesystem>
#include <iostream>  // cout
#include <memory>  // make_unique, unique_ptr
#include <string>

class Ppm
{
    const std::string file_extension{"ppm"};
public:
    Ppm(std::filesystem::path path)
    : path_{path.replace_extension(file_extension)}
    {
        
        std::cout << "Ppm ctor: " << path_ << "\n";
    }
    ~Ppm() { std::cout << "Ppm dtor\n"; }
private:
    std::filesystem::path path_{};
};

class PixelHandler
{
public:
    PixelHandler(std::filesystem::path path)
    : ppm_up_{std::make_unique<Ppm>(std::move(path))}
    {}
    ~PixelHandler() { std::cout << "PixelHandler dtor\n"; }
private:
    std::unique_ptr<Ppm> ppm_up_{};
};

int main()
{
    PixelHandler ph("blah.jpg");
    std::cout << "\n... short life :(\n\n";
}

【讨论】:

  • @TedLyngmo 谢谢!我首先写了path_{std::move(file_path.replace_extension(file_extension))},但后来我认为修改然后移动它不是一个好主意。
  • 非常感谢! :) 你不必删除你的 cmets。他们很有教育意义,尤其是最后一个。
  • Oups... 我已经忘记了我在其中写了什么,但我认为你的回答不言自明,所以我删除了我的杂谈。 :)
猜你喜欢
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多