【问题标题】:Pass object reference into different class object array using public function使用公共函数将对象引用传递到不同的类对象数组
【发布时间】:2013-10-04 20:42:32
【问题描述】:

给定 A 类和 B 类。我需要使用 cpp 文件中所示的“add”函数将 B 类的对象引用存储在 A 类的对象数组中。

我应该可以使用 cpp 文件中所示的“->”来调用 B 类的“打印”函数。

编译时错误:void* 不是指向对象的指针类型

那么我该如何解决这个错误呢?

================================================ ====================================

// 头文件

// ABC.h

class A{
     private:
        size_t size_;
        void * a_[256];
        static int index_;
    public:
        void add(void * obj);
        void * operator[](int x){
            return a_[x];
        }


};

class B {
    private:
        const char * f_;
        const char * l_;

    public:
        B(const char * fn, const char * loc ):f_(fn), l_(loc){ A(); };
        void print();
};

// cpp文件

#include "ABC.h"

int A::index_ = 0;

inline void A::add(void* obj){

    void * insertionPoint = static_cast<char *>(a_[index_]) + ( size_ * index_ );

    memcpy( insertionPoint, obj,  size_);

    ++index_;

}

inline void B::print(){
    ...
}

int main()
{
    A a;

    B b( "Name", "Some string");

    a.add( &b );

    a[0]->print(); // <-- This should be an object reference to B, but it is producing the error.

    return 0;
}

输出:

命名一些字符串

【问题讨论】:

  • 什么意思你一切正常?上面的代码完全被破坏了。 A::print 的实现在哪里? BC 中的 print 函数不会覆盖 A 中的函数。此外,A 没有实现operator[]。最后,您希望在这里发生什么...*this = dynamic_cast&lt;void*&gt;(obj);?我也很想知道您选择避开标准库的哪一部分,以及出于什么原因。
  • 我认为 main 中的代码是他想要做的一个例子。因为他说除了存储类对象 b 和 c 的引用之外,一切都在工作。 @Praetorian 是对的,但对 *this 的分配非常可疑。
  • @Praetorian 你能解释一下如果 A DID 实现 operator[] 我可以用 A 做什么吗?
  • 如果你实现了A::operator[],那么a[0]-&gt;print();这个语句就有意义了。您似乎对继承也有一些误解。如果您想要A 充当B 实例的容器,则不必让B 派生自A

标签: c++ arrays class c++11 polymorphism


【解决方案1】:

下面的方法没有意义:

virtual void add(A * obj){
    *this = dynamic_cast<void*>(obj);
}

如果您想在A 中存储指向A 的其他实例的指针,请创建一个指针数组来保存它们,尝试“替换”当前实例(即*this =...)没有意义。

另请注意,如果您想检查 A* 是否指向 B 的实例,dynamic_cast 会有意义:

A* a = new B();
// in compile time it's A*, but does it really point to instance of B? :
B* b = dynamic_cast<B*>(a);

为什么不从更简单的开始?比方说:

class A {
public:
    virtual void print() { std::cout << "a"; }
};

class B : public A {
public:
    void print() /* const */ { std::cout << "b"; }
};

用作:

A* a = new A();
A* b = new B();
a->print();
b->print();

(就目前而言)输出ab。然后您可以将Bprint() 更改为const 并意识到const 的方法实际上很重要。

【讨论】:

  • 是的,你是对的。这只是我尝试尝试任何事情来让它发挥作用。我已将我的问题修改为更具体。对此感到抱歉。
【解决方案2】:

解决方案涉及上述所有 cmets 的建议

比较问题和答案之间的差异以全面了解解决方案。

我需要做的是将 A 类的私有 a_ 成员更改为类型 A:A * _a[256]
下一条:我还需要将 operator[] 和 add 方法的参数更改为 A 类型:A * operator[](A * obj)
下一条:我需要为 A 类添加一个用于继承目的的虚拟 void print()。
最后:B 类需要继承 A 类

下面是工作代码

注意:我不确定这段代码是否完全安全或正确处理内存问题,但我知道它会打印以输出它打算打印的内容。

================================================ ====================================

// 头文件

// ABC.h

class A{
     private:
        size_t size_;
        A * a_[256];
        static int index_;
    public:
        void add(A * obj);
        A * operator[](int x); // Any subclass object reference of A can be assigned now. 
        virtual void print()const; // Virtual tells the compiler to look for other void print methods first.


};

class B : public A{
    private:
        const char * f_;
        const char * l_;

    public:
        B(const char * fn, const char * loc ):f_(fn), l_(loc){ A(); };
        void print()const;
};

// cpp文件

#include "ABC.h"

int A::index_ = 0; // Need to call this here because it is declared static in Class A and can be used dynamically. 

inline A * A::operator[](int x){
    return a_[x]; // Implements operator[], so class A can act like a container.
}

inline void A::add(A* obj){

    a_[index_] = obj; // Adds a base or subclass object reference to class A object array.

    ++index_; // Need this to remember current index of object reference A's array.

}

inline void A::print()const{}

inline void B::print()const{

    std::cout <<  "B " << firstname_ << " works in " << location_ << std::endl;

}

int main()
{
    A a;

    B b( "Name", "Some string");

    a.add( &b );

    a[0]->print();

    return 0;
}

输出:

命名一些字符串

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 2021-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多