2

これをはっきりさせてください。これは私が今まで解決できなかったインタビューの質問です。2 つのクラスを考えてみましょう

class A
{
     public : virtual int f() { };
              int a;
 }

class B : public A
{

     public : virtual int g() { };
              int b;
}

A のサイズを尋ねられたとき、BI は正しく 8 と 12 と答えました。次の質問は、A から派生した最初の 8 バイトを無視するようにクラス B を定義する方法でした。私はまだそれがどのように可能か理解できません。これがどのように行われるかを誰かが説明できますか?

編集:本当の問題は、クラスのサイズを見つけることではなく、フォローアップです。

4

2 に答える 2

0

これはインタビュアーの質問に直接答えるものではありませんが、A と B の継承を操作する別の方法として、次のような方法があります。

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

//This concept was taken from a Going Native 2013 talk called "C++ Seasoning" given by Sean Parent
//
//Located here: (about 101 minutes into it)
//http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning

//Polymorphism without inheritance.
//Permits polymorphism without using pointers or references,
//and allows them to be copied around easier (each instance is actually its own object) rather
//than accidentally shallow-copying when you wanted deep-copies.
//
//Every time Object::Print() is called, it calls
// Object::PrintableConcept::Print(), which virtually calls
// Object::PrintableModel<TYPE>::Print(), which calls your
// "derived" class that implements the Print() function, regardless
// of what that class inherits (if anything).
class Object //Class without inheritance or virtual.
{
    public:
    template<typename Type>
    Object(Type instance) : self(std::make_shared<PrintableModel<Type>>(std::move(instance)))
    { }

    //Calls the "inherited" function.
    void Print() const
    {
        self->Print();
    }

    private:
    struct PrintableConcept //The concept we want to polymorphably access.
    {
        virtual ~PrintableConcept() = default;
        virtual void Print() const = 0;
    };

    //The class that concretely models the concept,
    //and does the actual inheritting.
    template<typename Type>
    struct PrintableModel : public PrintableConcept
    {
        PrintableModel(Type instance) : data(std::move(instance)) { }

        //Every time 
        void Print() const override
        {
            this->data.Print();
        }

        Type data;
    };

    //This should be a unique_ptr, but you also need to make sure
    //you implement proper copy operators in this class and move support.
    std::shared_ptr<PrintableConcept> self;
};

class Whatever
{
    public:
    void Print() const { std::cout << "Whatever\n" << std::endl; }
};

class SomethingElse
{
    public:
    void Print() const { std::cout << "SomethingElse\n" << std::endl; }
};

class WidgetThing
{
    public:
    void Print() const { std::cout << "WidgetThing\n" << std::endl; }
};

typedef std::vector<Object> Document;

int main()
{
    Document document;
    document.emplace_back(Whatever());
    document.emplace_back(SomethingElse());
    document.emplace_back(WidgetThing());

    for(const auto &object : document)
    {
        object.Print();
    }

    return 0;
}

<<<コードを実行する>>>

実際には「オブジェクト」(または他のもの) から継承するクラスはありませんが、オブジェクトがテンプレートとしてアクセスする共通のインターフェイス ( ) をすべて実装しているため、ベクトルなどで相互に交換可能に使用できますがPrintableConcept、オブジェクト自体はそうではありません。 't はテンプレートとならないので、どちらが別々の型になっObject<something>ていたでしょう。Object<something-else>

于 2013-10-02T17:21:54.833 に答える