const member functions and const return values

本文深入探讨了C++中const成员函数的使用及其与非const版本的区别,包括函数返回值的特性、const对象与非const对象调用函数时的行为差异,以及const函数如何提供更灵活的操作方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Why there are two function's versions in one class(const and non-const)? Let's have a test now.


#include <iostream>
using namespace std;

class A
{
public:
	A() {}
	void fun() { cout<<"I am not const."<<endl; }
	void fun() const { cout<<"I am const."<<endl; }
};

int main()
{
	A test1;
	test1.fun();

	const A test2;
	test2.fun();

	return 0;
}


It is clear to see that the const object will match the const version. However, what happens when we don't have the const member function?

#include <iostream>
using namespace std;

class A
{
public:
	A() {}
	void fun() { cout<<"I am not const."<<endl; }
//	void fun() const { cout<<"I am const."<<endl; }
};

int main()
{
	A test1;
	test1.fun();

	const A test2;
	test2.fun();

	return 0;
}


An error occurs here. How about lacking of the non-const member function version?

#include <iostream>
using namespace std;

class A
{
public:
	A() {}
//	void fun() { cout<<"I am not const."<<endl; }
	void fun() const { cout<<"I am const."<<endl; }
};

int main()
{
	A test1;
	test1.fun();

	const A test2;
	test2.fun();

	return 0;
}


It runs well. However, there is a difference--both const!

The conclusion is that const function is more flexible, while the non-const version is relatively strict.


What about the const return values? Let's see.

#include <iostream>
using namespace std;

class A
{
public:
	A() { a=0; }
	int& fun() { cout<<"I am not const."<<endl; return a; }
	const int& fun() const { cout<<"I am const."<<endl; return a; }
	void get() { cout<<"Its value is "<<a<<endl; }
private:
	int a;
};

int main()
{
	A test1;
	test1.get();
	test1.fun() = 10;
	test1.get();

	return 0;
}

The value has been changed. Notice that it is a private member value. Now try the const version.


#include <iostream>
using namespace std;

class A
{
public:
	A() { a=0; }
	int& fun() { cout<<"I am not const."<<endl; return a; }
	const int& fun() const { cout<<"I am const."<<endl; return a; }
	void get() { cout<<"Its value is "<<a<<endl; }
private:
	int a;
};

int main()
{
	A test1;
	test1.get();
	test1.fun() = 10;
	test1.get();

	const A test2;
	test2.fun() = 10;

	return 0;
}


In conclusion, through "&" we can change the private value in class, while it doesn't work provided it is a const return value.















                
是在这个类中查看版本么namespace OpenXLSX { constexpr const char * XLXmlDefaultVersion = "1.0"; constexpr const char * XLXmlDefaultEncoding = "UTF-8"; constexpr const bool XLXmlStandalone = true; constexpr const bool XLXmlNotStandalone = false; /** * @brief The XLXmlSavingDeclaration class encapsulates the properties of an XML saving declaration, * that can be used in calls to XLXmlData::getRawData to enforce specific settings */ class OPENXLSX_EXPORT XLXmlSavingDeclaration { public: // ===== PUBLIC MEMBER FUNCTIONS ===== // XLXmlSavingDeclaration() : m_version(XLXmlDefaultVersion), m_encoding(XLXmlDefaultEncoding), m_standalone(XLXmlNotStandalone) {} XLXmlSavingDeclaration(XLXmlSavingDeclaration const & other) = default; // copy constructor XLXmlSavingDeclaration(std::string version, std::string encoding, bool standalone = XLXmlNotStandalone) : m_version(version), m_encoding(encoding), m_standalone(standalone) {} ~XLXmlSavingDeclaration() {} /** * @brief: getter functions: version, encoding, standalone */ std::string const & version() const { return m_version; } std::string const & encoding() const { return m_encoding; } bool standalone_as_bool() const { return m_standalone; } std::string const standalone() const { return m_standalone ? "yes" : "no"; } private: // ===== PRIVATE MEMBER VARIABLES ===== // std::string m_version; std::string m_encoding; bool m_standalone; }; /** * @brief The XLXmlData class encapsulates the properties and behaviour of the .xml files in an .xlsx file zip * package. Objects of the XLXmlData type are intended to be stored centrally in an XLDocument object, from where * they can be retrieved by other objects that encapsulates the behaviour of Excel elements, such as XLWorkbook * and XLWorksheet. */ class OPENXLSX_EXPORT XLXmlData final { public: // ===== PUBLIC MEMBER FUNCTIONS ===== // /** * @brief Default constructor. All member variables are default constructed. Except for * the raw XML data, none of the member variables can be modified after construction. Hence, objects created * using the default constructor can only serve as null objects and targets for the move assignemnt operator. */ XLXmlData() = default; /** * @brief Constructor. This constructor creates objects with the given parameters. the xmlId and the xmlType * parameters have default values. These are only useful for relationship (.rels) files and the * [Content_Types].xml file located in the root directory of the zip package. * @param parentDoc A pointer to the parent XLDocument object. * @param xmlPath A std::string with the file path in zip package. * @param xmlId A std::string with the relationship ID of the file (used in the XLRelationships class) * @param xmlType The type of object the XML file represents, e.g. XLWorkbook or XLWorksheet. */ XLXmlData(XLDocument* parentDoc, const std::string& xmlPath, const std::string& xmlId = "", XLContentType xmlType = XLContentType::Unknown); /** * @brief Default destructor. The XLXmlData does not manage any dynamically allocated resources, so a default * destructor will suffice. */ ~XLXmlData(); /** * @brief check whether class is linked to a valid XML document * @return true if the class should have a link to valid data * @return false if accessing any other properties / methods could cause a segmentation fault */ bool valid() const { return m_xmlDoc != nullptr; } /** * @brief Copy constructor. The m_xmlDoc data member is a XMLDocument object, which is non-copyable. Hence, * the XLXmlData objects have a explicitly deleted copy constructor. * @param other */ XLXmlData(const XLXmlData& other) = delete; /** * @brief Move constructor. All data members are trivially movable. Hence an explicitly defaulted move * constructor is sufficient. * @param other */ XLXmlData(XLXmlData&& other) noexcept = default; /** * @brief Copy assignment operator. The m_xmlDoc data member is a XMLDocument object, which is non-copyable. * Hence, the XLXmlData objects have a explicitly deleted copy assignment operator. */ XLXmlData& operator=(const XLXmlData& other) = delete; /** * @brief Move assignment operator. All data members are trivially movable. Hence an explicitly defaulted move * constructor is sufficient. * @param other the XLXmlData object to be moved from. * @return A reference to the moved-to object. */ XLXmlData& operator=(XLXmlData&& other) noexcept = default; /** * @brief Set the raw data for the underlying XML document. Being able to set the XML data directly is useful * when creating a new file using a XML file template. E.g., when creating a new worksheet, the XML code for * a minimum viable XLWorksheet object can be added using this function. * @param data A std::string with the raw XML text. */ void setRawData(const std::string& data); /** * @brief Get the raw data for the underlying XML document. This function will retrieve the raw XML text data * from the underlying XMLDocument object. This will mainly be used when saving data to the .xlsx package * using the save function in the XLDocument class. * @param savingDeclaration @optional specify an XML saving declaration to use * @return A std::string with the raw XML text data. */ std::string getRawData(XLXmlSavingDeclaration savingDeclaration = XLXmlSavingDeclaration{}) const; /** * @brief Access the parent XLDocument object. * @return A pointer to the parent XLDocument object. */ XLDocument* getParentDoc(); /** * @brief Access the parent XLDocument object. * @return A const pointer to the parent XLDocument object. */ const XLDocument* getParentDoc() const; /** * @brief Retrieve the path of the XML data in the .xlsx zip archive. * @return A std::string with the path. */ std::string getXmlPath() const; /** * @brief Retrieve the relationship ID of the XML file. * @return A std::string with the relationship ID. */ std::string getXmlID() const; /** * @brief Retrieve the type represented by the XML data. * @return A XLContentType getValue representing the type. */ XLContentType getXmlType() const; /** * @brief Access the underlying XMLDocument object. * @return A pointer to the XMLDocument object. */ XMLDocument* getXmlDocument(); /** * @brief Access the underlying XMLDocument object. * @return A const pointer to the XMLDocument object. */ const XMLDocument* getXmlDocument() const; /** * @brief Test whether there is an XML file linked to this object * @return true if there is no underlying XML file, otherwise false */ bool empty() const; private: // ===== PRIVATE MEMBER VARIABLES ===== // XLDocument* m_parentDoc {}; /**< A pointer to the parent XLDocument object. >*/ std::string m_xmlPath {}; /**< The path of the XML data in the .xlsx zip archive. >*/ std::string m_xmlID {}; /**< The relationship ID of the XML data. >*/ XLContentType m_xmlType {}; /**< The type represented by the XML data. >*/ mutable std::unique_ptr<XMLDocument> m_xmlDoc; /**< The underlying XMLDocument object. >*/ }; } // namespace OpenXLSX
最新发布
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值