由我自己解决。指针,但我不知道为什么

时间:2017-09-22 21:32:07

标签: c++ class

这是我不明白的。有2个类:ClassA和ClassB。 当我通过参数构造函数创建classB时,指针指向ClassA ..这个对象是删除(析构函数运行他的函数) 。 (已经解决了,但我不知道为什么?) (这是否正常?只想写没有逻辑错误) 我通过改变“*”的位置来解决它。来自

    pointerB = new ClassB(*this);
to
    pointerB = new ClassB(this);

and
ClassB::ClassB(ClassA pointer)
to
ClassB::ClassB(ClassA *pointer)

旧代码:

main.cpp
#include "stdafx.h"
#include <iostream>
#include "ClassA.h"
#include "ClassB.h"

    int main()
    {
        //pointer for object ClassA
        ClassA *A;
        //New Object
        A = new ClassA();



        getchar();
        return 0;
    }

ClassA.cpp

    #include "stdafx.h"
    #include "ClassA.h"


    ClassA::ClassA()
    {
        std::cout << "CLASS A OBJECT CREATED" << std::endl;
        //Creation of B
        pointerB = new ClassB();
        pointerB = new ClassB(*this);
    }


    ClassA::~ClassA()
    {
        std::cout << "CLASS A OBJECT DELETED" << std::endl;
    }

ClassA.h

    #pragma once
    #include <iostream>
    #include "ClassB.h"
    extern class ClassB;
    class ClassA
    {
        ClassB *pointerB;
    public:
        ClassA();
        ~ClassA();
    };
ClassB.cpp

    #include "stdafx.h"
    #include "ClassB.h"


    ClassB::ClassB()
    {
        std::cout << "CLASS B OBJECT CREATED by constructor" << std::endl;

    }
    ClassB::ClassB(ClassA pointer) {
        std::cout << "CLASS B OBJECT CREATED with pointer" << std::endl;
    }

    ClassB::~ClassB()
    {
        std::cout << "CLASS B OBJECT DELETED" << std::endl;
    }
ClassB.h

    #pragma once
    #include <iostream>
    #include "ClassA.h"
    extern class ClassA;
    class ClassB
    {
        ClassA * pointerA;

    public:
        ClassB();
        ClassB(ClassA *pointer);
        ~ClassB();
    };

2 个答案:

答案 0 :(得分:1)

在声明ClassB::ClassB(ClassA pointer)中,构造函数的参数是ClassA 类型的对象,而不是指向类型为ClassA的对象的指针。因此,您必须在旧代码中取消引用this指针。在调用pointerB = new ClassB(*this);中,ClassB的构造函数接收this指向的实例,但该实例的副本 。该调用返回后, copy 将被删除。这就是为什么你看到ClassA的析构函数被调用的原因。如果在构造函数和析构函数中输出this指针(例如十六进制整数),您会看到构造函数和析构函数中有一个不同的this指针。或者更好:使用调试器,你会看到这一点。您还可以为ClassA声明一个复制构造函数,然后您会看到它在pointerB = new ClassB(*this);中被调用。

现在,如果您希望将this指向的实例传递给ClassB的构造函数,您可以通过将其声明为您在解决方案中所做的指针来实现,或者您可以传递它作为参考。例如。您将ClassB的构造函数声明为

 ClassB::ClassB(ClassA& aClassA) {}

然后,您可以在没有复制pointerB = new ClassB(*this);对象的情况下调用ClassA

对您的代码的一些小评论:

  • 尽量避免头文件中不必要的依赖。您不需要#include <iostream>中的ClassA.h,因为ClassA.h中的任何内容都不依赖于ClassA.cpp。只有<iostream>中的代码取决于class ClassB;。所以,你应该把它包括在那里。

  • 前瞻性声明是一件好事,有助于避免不必要的包含。但语法只是extern(没有“#include "ClassB.h"”)。然后,您无需ClassA.h中的pointer

  • 如果某些内容不是指针,则不应将其称为 GlideApp.with(this).load("url").into(imageView); 。这可能是所有错误的根源。

答案 1 :(得分:0)

在更改之前,ClassA对象的副本已传递给ClassB构造函数。构造函数完成后,副本被销毁。这就是你从析构函数中看到打印件的原因。

默认情况下,编译器将创建复制构造函数,隐式将所有数据盲目地复制到内存中的新位置。如果要查看复制构造函数的调用,则应定义自己的构造函数,该构造函数接受相同类型ClassA(const ClassA&)的const引用。

更改后,传递已创建对象的地址,因此不会创建副本。

我不会说你的代码没问题。你打破了三个规则,因为你使用自己的析构函数并且无法创建复制构造函数和赋值运算符。见 - https://en.cppreference.com/w/cpp/language/rule_of_three。用“new”创建的对象也没有被正确删除。