关于多态性和穆利蒂遗传的问题

发布于 2025-02-06 21:17:08 字数 2737 浏览 3 评论 0原文

我希望以三种不同的方式存储数据:

1。储存到std :: String

2.写入文件描述符

3.两种方法

,我希望为这三个使用统一接口不同的方法。

我写了一个简单的代码sippet来实现上述目标。第一个&第二个确实很容易,但是对于第三局,我被卡住了。

请注意下面的代码段中的评论,如果store_by_fd_and_string定义了编译器,则编译器会抱怨。

这是代码代码片段

#include <memory>
#include <iostream>
#include <unistd.h>
 
class DataStorage {
public:
  DataStorage(int total_count):total_count_(total_count){};
  virtual int Store(const char *buffer, int count) = 0;
  virtual ~DataStorage(){};

protected:
  int total_count_;
};

class DataStorageByStr : public DataStorage {
public:
  DataStorageByStr(std::string &str) : str_(str), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
    str_ += std::string(buffer, count);
    total_count_ += count;
    return 0;
  };

protected:
  std::string &str_;
};

class DataStorageByFd : public DataStorage {
public:
  DataStorageByFd(int &fd):fd_(fd), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
     int ret = write(fd_, buffer, count);
     if(ret > 0)
     {
         total_count_ += ret;
     }

     return ret;
  };

protected:
  int &fd_;
};

class DataStorageByStrAndFd : public DataStorageByStr, public DataStorageByFd {
public:
  DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd) {}
  
  int Store(const char *buffer, int count)
  {
    int ret1 = DataStorageByStr::Store(buffer, count);
    int ret2 = DataStorageByFd::Store(buffer, count);

    return ((0==ret1) && (0==ret2))?0:-1;
  }
};

int StoreSomeData(DataStorage *pstorage, const std::string data_to_store)
{
    return pstorage->Store(data_to_store.data(), data_to_store.length());
}

int main()
{
    {
        std::string str{"storing the string to std::string works !"};
        std::string data;

        DataStorage *pstorage = new DataStorageByStr(data);
        StoreSomeData(pstorage, str);

        std::cout << data << std::endl;
    }

    {
        std::string str{"storing the string to fd works !"};
        int fd = 1;

        DataStorage *pstorage = new DataStorageByFd(fd);
        StoreSomeData(pstorage, str);
    }



#ifdef STORE_BY_FD_AND_STRING
    {
        std::string str{"thanks for your attention for this matter!"};

        std::string data;
        int fd = 1;

        DataStorage *pstorage = new DataStorageByStrAndFd(str, fd); //The compiler complain that 'DataStorage' is an ambiguous base of 'DataStorageByStrAndFd'
        StoreSomeData(pstorage, str);
    }
#endif
}


任何实现所有上述目标的SUMENTION?

I hope to store the data in three different ways:

1.store to a std::string

2.write to file descriptor

3.both of the above

And I hope to use a uniform interface for these three different methods.

I wrote a simple code sippet to achieve the said goals. The first & second are easy indeed, but for the third I am stuck.

Please pay attention to the comment in the code snippet below, which is what the compiler complains if STORE_BY_FD_AND_STRING is defined.

Here is the code snippet:

#include <memory>
#include <iostream>
#include <unistd.h>
 
class DataStorage {
public:
  DataStorage(int total_count):total_count_(total_count){};
  virtual int Store(const char *buffer, int count) = 0;
  virtual ~DataStorage(){};

protected:
  int total_count_;
};

class DataStorageByStr : public DataStorage {
public:
  DataStorageByStr(std::string &str) : str_(str), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
    str_ += std::string(buffer, count);
    total_count_ += count;
    return 0;
  };

protected:
  std::string &str_;
};

class DataStorageByFd : public DataStorage {
public:
  DataStorageByFd(int &fd):fd_(fd), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
     int ret = write(fd_, buffer, count);
     if(ret > 0)
     {
         total_count_ += ret;
     }

     return ret;
  };

protected:
  int &fd_;
};

class DataStorageByStrAndFd : public DataStorageByStr, public DataStorageByFd {
public:
  DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd) {}
  
  int Store(const char *buffer, int count)
  {
    int ret1 = DataStorageByStr::Store(buffer, count);
    int ret2 = DataStorageByFd::Store(buffer, count);

    return ((0==ret1) && (0==ret2))?0:-1;
  }
};

int StoreSomeData(DataStorage *pstorage, const std::string data_to_store)
{
    return pstorage->Store(data_to_store.data(), data_to_store.length());
}

int main()
{
    {
        std::string str{"storing the string to std::string works !"};
        std::string data;

        DataStorage *pstorage = new DataStorageByStr(data);
        StoreSomeData(pstorage, str);

        std::cout << data << std::endl;
    }

    {
        std::string str{"storing the string to fd works !"};
        int fd = 1;

        DataStorage *pstorage = new DataStorageByFd(fd);
        StoreSomeData(pstorage, str);
    }



#ifdef STORE_BY_FD_AND_STRING
    {
        std::string str{"thanks for your attention for this matter!"};

        std::string data;
        int fd = 1;

        DataStorage *pstorage = new DataStorageByStrAndFd(str, fd); //The compiler complain that 'DataStorage' is an ambiguous base of 'DataStorageByStrAndFd'
        StoreSomeData(pstorage, str);
    }
#endif
}


Any sugestion to achieve all the aforementioned goals?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜妞爱困 2025-02-13 21:17:09

感谢@sam varshavchik @adrian mole。此代码段有效。

#include <memory>
#include <iostream>
#include <unistd.h>
 
class DataStorage {
public:
  DataStorage(int total_count):total_count_(total_count){};
  virtual int Store(const char *buffer, int count) = 0;
  virtual ~DataStorage(){};

protected:
  int total_count_;
};

class DataStorageByStr : virtual public  DataStorage {
public:
  DataStorageByStr(std::string &str) : str_(str), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
    str_ += std::string(buffer, count);
    total_count_ += count;
    return 0;
  };

protected:
  std::string &str_;
};

class DataStorageByFd :virtual public  DataStorage {
public:
  DataStorageByFd(int &fd):fd_(fd), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
     int ret = write(fd_, buffer, count);
     if(ret > 0)
     {
         total_count_ += ret;
     }

     return ret;
  };

protected:
  int &fd_;
};

class DataStorageByStrAndFd : public  DataStorageByStr, public  DataStorageByFd {
public:
  DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd), DataStorage(0)
  {
    
  }
  
  int Store(const char *buffer, int count)
  {
    int ret1 = DataStorageByStr::Store(buffer, count);
    int ret2 = DataStorageByFd::Store(buffer, count);

    return ((0==ret1) && (0==ret2))?0:-1;
  }
};

int StoreSomeData(DataStorage *pstorage, const std::string data_to_store)
{
    return pstorage->Store(data_to_store.data(), data_to_store.length());
}

int main()
{
    {
        std::string str{"storing the string to std::string works !"};
        std::string data;

        DataStorage *pstorage = new DataStorageByStr(data);
        StoreSomeData(pstorage, str);

        std::cout << data << std::endl;
    }

    {
        std::string str{"storing the string to fd works !"};
        int fd = 1;

        DataStorage *pstorage = new DataStorageByFd(fd);
        StoreSomeData(pstorage, str);
    }



#ifndef STORE_BY_FD_AND_STRING
    {
        std::string str{"thanks for your attention for this matter!"};

        std::string data;
        int fd = 1;

        DataStorage *pstorage = new DataStorageByStrAndFd(str, fd); //The compiler complain that 'DataStorage' is an ambiguous base of 'DataStorageByStrAndFd'
        StoreSomeData(pstorage, str);
    }
#endif
}

说明

“在此处输入图像描述”

虚拟继承是一种C ++技术,可确保仅孙子派生的类别继承了一个base类成员变量的副本。没有虚拟继承,如果两个B和C类从A类继承,而A类也从B和C继承,则D将包含A的成员变量的两个副本:一个通过B,一个通过C使用范围分辨率独立访问。

相反,如果B和C类几乎从A类继承,则D类的对象将仅包含一组来自A类的成员变量。

此功能对于多个继承最有用,因为它使虚拟基础成为常见的子对象派生类及其从中得出的所有类。这可以用来避免钻石问题,通过澄清含糊的含义,从衍生班的角度来看(上面的示例中)虚拟基础(a)的作用(d) D,不是通过基础(B或C)间接得出的类。

Thanks to @Sam Varshavchik @Adrian Mole. This code snippet works.

#include <memory>
#include <iostream>
#include <unistd.h>
 
class DataStorage {
public:
  DataStorage(int total_count):total_count_(total_count){};
  virtual int Store(const char *buffer, int count) = 0;
  virtual ~DataStorage(){};

protected:
  int total_count_;
};

class DataStorageByStr : virtual public  DataStorage {
public:
  DataStorageByStr(std::string &str) : str_(str), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
    str_ += std::string(buffer, count);
    total_count_ += count;
    return 0;
  };

protected:
  std::string &str_;
};

class DataStorageByFd :virtual public  DataStorage {
public:
  DataStorageByFd(int &fd):fd_(fd), DataStorage(0){};
  int Store(const char *buffer, int count)
  {
     int ret = write(fd_, buffer, count);
     if(ret > 0)
     {
         total_count_ += ret;
     }

     return ret;
  };

protected:
  int &fd_;
};

class DataStorageByStrAndFd : public  DataStorageByStr, public  DataStorageByFd {
public:
  DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd), DataStorage(0)
  {
    
  }
  
  int Store(const char *buffer, int count)
  {
    int ret1 = DataStorageByStr::Store(buffer, count);
    int ret2 = DataStorageByFd::Store(buffer, count);

    return ((0==ret1) && (0==ret2))?0:-1;
  }
};

int StoreSomeData(DataStorage *pstorage, const std::string data_to_store)
{
    return pstorage->Store(data_to_store.data(), data_to_store.length());
}

int main()
{
    {
        std::string str{"storing the string to std::string works !"};
        std::string data;

        DataStorage *pstorage = new DataStorageByStr(data);
        StoreSomeData(pstorage, str);

        std::cout << data << std::endl;
    }

    {
        std::string str{"storing the string to fd works !"};
        int fd = 1;

        DataStorage *pstorage = new DataStorageByFd(fd);
        StoreSomeData(pstorage, str);
    }



#ifndef STORE_BY_FD_AND_STRING
    {
        std::string str{"thanks for your attention for this matter!"};

        std::string data;
        int fd = 1;

        DataStorage *pstorage = new DataStorageByStrAndFd(str, fd); //The compiler complain that 'DataStorage' is an ambiguous base of 'DataStorageByStrAndFd'
        StoreSomeData(pstorage, str);
    }
#endif
}

Explanation:

enter image description here

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes. Without virtual inheritance, if two classes B and C inherit from a class A, and a class D inherits from both B and C, then D will contain two copies of A's member variables: one via B, and one via C. These will be accessible independently, using scope resolution.

Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A.

This feature is most useful for multiple inheritance, as it makes the virtual base a common subobject for the deriving class and all classes that are derived from it. This can be used to avoid the diamond problem by clarifying ambiguity over which ancestor class to use, as from the perspective of the deriving class (D in the example above) the virtual base (A) acts as though it were the direct base class of D, not a class derived indirectly through a base (B or C).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文