C++ 析构函数:无法访问在 class 中声明的私有成员

C++ Destructor: cannot access private member declared in class

我正在尝试使用 C++ 创建一个简单的程序,它使用 2 classes 创建电影列表:Movie,其中包含一部电影的详细信息,Movies,其中包含电影对象的名称和向量。重点是用户应该只与 class Movies 交互,因此我选择将 Movie class 的所有成员(包括数据和方法)私人。

如果我让 Movie::~Movie() 保持原样,我会不断收到以下错误,但如果我在 .h 和 .cpp 中对其进行注释,它就可以正常工作。

我已明确将 Movies class 设为 Movie class 的 朋友,因此它可以访问其所有成员.

error from Visual Studio Community 2019

Movie.h:

#pragma once
#include<iostream>
#include<string>

class Movie
{
    friend class Movies;
private:
    std::string name;
    std::string rating;
    int watchedCounter;
    int userRating;
    std::string userOpinion;

    // methods also private because the user should only interact with the Movies class, which is a friend of class Movie
    std::string get_name() const;

    Movie(std::string nameVal = "Default Name", std::string ratingVal = "Default Rating", int watchedCounterVal = 0, int userRatingVal = 0, std::string userOpinionVal = "");

    ~Movie();
};

Movie.cpp:

#include "Movie.h"

// Name getter
std::string Movie::get_name() const
{
    return this->name;
}


///*
// Destructor
Movie::~Movie()
{
    std::cout << "Movie destructor called for: " << this->name << std::endl;
}
//*/


// Constructor
Movie::Movie(std::string nameVal, std::string ratingVal, int watchedCounterVal, int userRatingVal, std::string userOpinionVal) : name{ nameVal }, rating{ ratingVal }, watchedCounter{ watchedCounterVal }, userRating{ userRatingVal }, userOpinion{userOpinionVal}
{
    std::cout << "Movie constructor called for: " << name << std::endl;
}

Movies.h:

#pragma once
#include<iostream>
#include<vector>
#include "Movie.h"

class Movies
{
private:
    std::string listName;
    std::vector<Movie> vectOfMovies;
    static int listNumber;

public:
    Movies(std::string listNameVal = "Default User's Movie List ");
    ~Movies();

    std::string get_listName() const;
    void addMovie(Movie m);
};

Movies.cpp:

#include<string>
#include "Movies.h"

int Movies::listNumber = 0;

// Constructor
Movies::Movies(std::string listNameVal) : listName{listNameVal}
{
    ++listNumber;
    listName += std::to_string(listNumber);
    std::cout << "MovieS constructor called for: " << listName << std::endl;
}


// Destructor
Movies::~Movies()
{
    std::cout << "MovieS destructor called for: " << listName << std::endl;
}


std::string Movies::get_listName() const
{
    return this->listName;
}


//Add movie to list of movies
void Movies::addMovie(Movie m)
{
    this->vectOfMovies.push_back(m);
}

以及主要的 .cpp 文件:

#include <iostream>
// #include "Movie.h"
#include "Movies.h"


int main()
{
    Movies moviesObj;

    moviesObj.get_listName();
    return 0;
}

如果 constructor/destructor 声明为私有,则 class 无法实例化。如果 destructor 是私有的,那么对象也只能从 class 中删除。此外,它还阻止 class 被继承(或者至少,阻止继承的 class 成为 instantiated/destroyed)。

将析构函数设为私有的用法:

任何时候你想让其他 class 负责你的 class' 对象的生命周期,或者你有理由阻止对象的破坏,你可以使析构函数私人。

例如,如果您正在做某种引用计数的事情,您可以让对象(或已成为“朋友”的管理器)负责计算对其自身的引用数量,并在数字为零。当仍然有对它的引用时,私有 dtor 会阻止任何其他人删除它。

再举一个例子,如果你有一个对象有一个管理器(或它自己),它可能会销毁它或可能拒绝销毁它,这取决于程序中的其他条件,例如数据库连接处于打开状态或正在写入的文件。您可以在 class 或管理器中使用“request_delete”方法来检查该条件,它将删除或拒绝,并且 return 状态告诉您它做了什么。这比仅仅调用“删除”要灵活得多。

因此,我建议您可以将 ~Movie(); 声明为 public。那么,问题就迎刃而解了。