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。那么,问题就迎刃而解了。
我正在尝试使用 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。那么,问题就迎刃而解了。