C++ 析构函数:无法访问类中声明的私有成员
Posted
技术标签:
【中文标题】C++ 析构函数:无法访问类中声明的私有成员【英文标题】:C++ Destructor: cannot access private member declared in class 【发布时间】:2021-02-17 16:57:22 【问题描述】:我正在尝试用 C++ 创建一个简单的程序,它使用 2 个类 创建电影列表:Movie
,其中包含一部电影的详细信息,@987654323 @,其中包含一个名称和一个电影对象的向量。重点是用户应该只与Movies
类交互,因此我选择将Movie
类的所有成员(数据和方法)设为私有。
如果我让Movie::~Movie()
保持原样,我会不断收到以下错误,但如果我在 .h 和 .cpp 中都对其进行注释,它就可以正常工作。
我已明确将Movies
类设为Movie
类的朋友,因此它可以访问其所有成员。
error from Visual Studio Community 2019
电影.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();
;
电影.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 , userOpinionuserOpinionVal
std::cout << "Movie constructor called for: " << name << std::endl;
电影.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);
;
电影.cpp:
#include<string>
#include "Movies.h"
int Movies::listNumber = 0;
// Constructor
Movies::Movies(std::string listNameVal) : listNamelistNameVal
++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;
【问题讨论】:
为什么Movie
析构函数private
?几乎倾向于将其作为错字关闭。
@DragoșBocancea std::vector<Movie>
试图通过内部的delete []
调用调用Movie
的private
析构函数。因此,您要么不能使用std::vector<Movie>
,而需要自己手动完成所有内存管理,要么将Movie::~Movie()
设为public
函数。
因为我只应该通过 Movies 类访问 Movie 类的成员 -- 当你创建一个析构函数(或构造函数)private
时,则没有外部类可以创建或销毁这些对象,除非有其他public
方法来构造或销毁对象。
@DragoșBocancea -- 析构函数什么都不做或发射宇宙飞船都没关系。如果是private
,任何需要可用析构函数的实体,例如std::vector
,都会发出编译器错误。
@DragoșBocancea 我真的不明白为什么你有一个公共的addMovie
,但是任何客户端都无法使用它,因为Movie
无法构造,因为构造函数是@987654349 @.
【参考方案1】:
如果constructor/destructor
被声明为私有,则无法实例化该类。如果destructor
是私有的,那么也只能从类内部删除该对象。此外,它还阻止了类被继承(或者至少阻止了继承的类被实例化/销毁)。
将析构函数设为私有:
任何时候您希望其他类负责您的类对象的生命周期,或者您有理由阻止对象的销毁,您可以将析构函数设为私有。
例如,如果您正在做某种引用计数的事情,您可以让对象(或已“加为好友”的管理器)负责计算对自身的引用次数,并在数量达到时将其删除零。当仍有对它的引用时,私有 dtor 会阻止其他任何人删除它。
另外一个例子,如果你有一个对象有一个管理器(或它本身),它可能会根据程序中的其他条件(例如数据库连接打开或文件正在打开)销毁或拒绝销毁它,该怎么办?书面。您可以在类或管理器中有一个“request_delete”方法来检查该条件,它将删除或拒绝,并返回一个状态,告诉您它做了什么。这比仅仅调用“删除”要灵活得多。
所以,我建议您可以将~Movie();
声明为公开。那么问题就迎刃而解了。
【讨论】:
以上是关于C++ 析构函数:无法访问类中声明的私有成员的主要内容,如果未能解决你的问题,请参考以下文章
错误 C2248:“CObject::CObject”:当我在 MFC 中调用 hDC.SelectObject 函数时,无法访问在“CObject”类中声明的私有成员
错误 C2248:“klientPracownik::klientPracownik”:无法访问在“klientPracownik”类中声明的私有成员