C++构造函数/析构函数 设置成private的原因

news/2024/7/4 1:40:59 标签: c++, class, 设计模式, c
cle class="tags" href="/tags/CLASS.html" title=class>class="baidu_pl">
cle_content" class="tags" href="/tags/CLASS.html" title=class>class="article_content clearfix">
content_views" class="tags" href="/tags/CLASS.html" title=class>class="htmledit_views">

将构造函数࿰c;析构函数声明为私有和保护的࿰c;那么对象如何创建?
已经不能从外部调用构造函数了࿰c;但是对象必须被构造࿰c;应该如何解决࿰c;麻烦大家帮忙说明࿰c;关于构造࿰c;析构函数声明为私有和保护时的用法???

提出这个问题࿰c;说明你已经对c++有所思考了。

从语法上来讲࿰c;一个函数被声明为protected或者private࿰c;那么这个函数就不能从“外部”直接被调用了。
对于protected的函数࿰c;子类的“内部”的其他函数可以调用之。
而对于private的函数࿰c;只能被本类“内部”的其他函数说调用。

语法上就是这么规定的࿰c;你肯定也知道的咯。
那么为什么有时候将构造函数或者析构函数声明为protected的或者private的?

通常使用的场景如下:
1。如果你不想让外面的用户直接构造一个类(假设这个类的名字为A)的对象࿰c;而希望用户只能构造这个类A的子类࿰c;那你就可以将类A的构造函数/析构函数声明为protected࿰c;而将类A的子类的构造函数/析构函数声明为public。例如:

<code class="tags" href="/tags/CLASS.html" title=class>class="language-cpp">#include <iostream>
using namespace std;
class="tags" href="/tags/CLASS.html" title=class>class A
{ 
protected: 
    A(){}
public:
   void test(){
       cout << "call A test()" << endl;
   } 
};

class="tags" href="/tags/CLASS.html" title=class>class B : public A
{
    public: B(){}
    
};

int main(int argc, char** argv)
{
    A a; // error
    B b; // ok
    b.test();
}code>


 

2. 如果将构造函数/析构函数声明为private࿰c;那只能这个类的“内部”的函数才能构造这个类的对象了。这里所说的“内部”不知道你是否能明白࿰c;下面举个例子吧。
class="tags" href="/tags/CLASS.html" title=class>class A
{
private:
A(){ }
~A(){ }

public:
void Instance()//类A的内部的一个函数
{
A a;
}
};
上面的代码是能通过编译的。上面代码里的Instance函数就是类A的内部的一个函数。Instance函数体里就构建了一个A的对象。
但是࿰c;这个Instance函数还是不能够被外面调用的。为什么呢?
如果要调用Instance函数࿰c;必须有一个对象被构造出来。但是构造函数被声明为private的了。外部不能直接构造一个对象出来。
A aObj; // 编译通不过
aObj.Instance();
但是࿰c;如果Instance是一个static静态函数的话࿰c;就可以不需要通过一个对象࿰c;而可以直接被调用。如下:

<code class="tags" href="/tags/CLASS.html" title=class>class="language-cpp">#include <iostream>
using namespace std;

class="tags" href="/tags/CLASS.html" title=class>class A
{
private:
    A():data(10){ cout << "A" << endl; }
    ~A(){ cout << "~A" << endl; }

public:
    static A& Instance()
    {
        static A a;
        return a;
    }
    void Print()
    {
        cout << data << endl;
    }

private:
    int data;
};

int main(int argc, char** argv)
{
    A& ra = A::Instance();
    ra.Print();
}code>


 

上面的代码其实是class="tags" href="/tags/SheJiMoShi.html" title=设计模式>设计模式singleton模式的一个简单的C++代码实现。


还有一个情况是:通常将拷贝构造函数和operator=(赋值操作符重载)声明成private࿰c;但是没有实现体。
这个的目的是禁止一个类的外部用户对这个类的对象进行复制动作。

cle>

http://www.niftyadmin.cn/n/1629268.html

相关文章

从尾到头打印链表 | 逆序打印链表

面试题5&#xff1a;从尾到头打印链表 1.题目描述 题目&#xff1a;输入一个链表的头结点&#xff0c;从尾到头反过来打印出每个结点的值&#xff0c;链表结点定义如下&#xff1a; struct ListNode {int m_nKey;ListNode* m_pNext; }; 2.分析问题 通常打印是一个只读操作&…

[ZZ]计算机视觉、机器学习相关领域论文和源代码大集合

原文地址&#xff1a;[ZZ]计算机视觉、机器学习相关领域论文和源代码大集合作者&#xff1a;计算机视觉与模式 注&#xff1a;下面有project网站的大部分都有paper和相应的code。Code一般是C/C或者Matlab代码。 最近一次更新&#xff1a;2013-1-29 一、 特征提取Feature Extrac…

代码运行时间的测量方法【linux/window】

一&#xff0c;返回单位为毫秒 #include<windows.h> DWORD dwStart GetTickCount(); // 测试代码 DWORD dwTime GetTickCount() - dwStart; 注意&#xff1a;GetTickCount()精确度有限&#xff0c;跟CPU有关&#xff0c;一般精确度在16ms左…

重建二又树 | 根据先序遍历和中序遍历建立二叉树

面试题6&#xff1a;重建二又树 1.题目描述 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。二叉树结点的定义如下&#xff1a; typedef struct BtNode {struct BtNode* leftchild;struct Bt…

ubuntu linux重置密码

&#xff08;和网上的有点不一样&#xff0c;记录一下&#xff09; 1&#xff09;重启系统&#xff0c;同时长时间按住shift键进入grub菜单&#xff1a;GNU GRUB version 1.99-12ubuntu5&#xff08;如图一&#xff09; 2&#xff09;选择Ubuntu, with Linux 4.2.0-27generic (…

Linux shell 特殊符号学习总结

在shell中常用的特殊符号罗列如下&#xff1a;# ; ;; . , / \ string| ! $ ${} $? $$ $* "string"* ** ? : ^ $# $ command{} [] [[]] …

网页消息推送-Comet (web技术)

百度&#xff1a;Comet (web技术) 转载于:https://www.cnblogs.com/Tpf386/p/8671618.html

计算机网络 | 构造超网 | CIDR

目录 一.无分类编址CIDR&#xff08;构造超网&#xff09; 1.为什么要使用CIDR 2.网络前缀 3.路由聚合和构成超网 4.CIDO的其他表示方法 5.总结 一.无分类编址CIDR&#xff08;构造超网&#xff09; 1.为什么要使用CIDR 划分子网在一定程度上缓解了互联网在发展中遇到的…