MUYIXUE 发表于 2024-12-1 16:06:09

隐藏父类方法出现的问题

为了学习向量,题主写了一个测试命名空间,为了具体了解内存的运行过程,题主写了一个工具命名空间,存放重载的分配器,
下面是测试用例.

问题描述: 我在使用vector的时候,传入的不是标准库中的std::allocator<T>,
而是自己写的一个模板类my_allocator<T>,这个模板类继承自std::allocator<T>,
并且重载了父类std::allocate 的allocate 和dealocate方法,按照父类和子类同名
函数,父类函数会被隐藏,vector应该使用我写的allocate和dealocate,而不是使用继承的
父类的方法,因为它此时应该已经被隐藏了才对,各位高手,有没有直到跳过我的方法的原因的




//-----------------------------------------------------------------------------------//
//test.h
#pragma once
#include <iostream>
#include <array>
#include <vector>

using std::cout;
using std::endl;

namespace Vector
{
        using std::vector;
        using std::allocator;
        void test();
}

//-----------------------------------------------------------------------------------//
//Tools.h
#pragma once
#include <iostream>
#include <vector>


using std::cout;
using std::endl;


namespace Tools
{
        namespace Vector {
      template<typename T>
      class my_allocator : public std::allocator<T>
      {
      public:
            typedef T value_type;

            my_allocator() = default;
            my_allocator(const my_allocator&) {};
            ~my_allocator() = default;

            T* allocate(std::size_t n)
            {
                T* p = std::allocator<T>::allocate(n);
                std::cout << "在" << p << "分配" << n << "个字节" << std::endl;
                return p;
            }

            void deallocate(T* p, std::size_t n)
            {
                std::allocator<T>::deallocate(p, n);
                std::cout << "在" << p << "解分配" << n * sizeof(*p) << "个字节" << std::endl;
            }
      };

        }
       
};
//-----------------------------------------------------------------------------------//
//test.cpp
#include "Test.h"
#include "Tools.h"
void Vector::test()
{
        cout << "当前测试项: vector:" << endl;
        cout << "................." << endl << endl;

        //设置容器中的值 - 2种方法
        //1. 使用构造函数 - const std::initializer_list作为传入参数
        cout << "vector<int, allocator<int>> vec = { 1,2,3,4,5 } : ";
        vector<int, allocator<int>> vec = { 1,2,3,4,5 };//初始化为拥有5个元素的向量
        for (int i : vec)//ranged-base for
        {
                cout << i << " ";
        }
        cout << endl;

        //2.使用assign
        cout << "vec.assign(5,1) :";
        vec.assign(5, 1);
        for (int i : vec)
        {
                cout << i <<" ";
        }
        cout << endl << endl;

        //访问并且设置向量单个元素的值 - 分为特殊位置和一般位置的单个元素
        //1. at的安全访问
        cout << "访问向量单个元素功能测试: " << endl;
        cout << "vec.at(1): " << vec.at(1) << endl;
        cout << "vec.at(1) = 0;-> " << "arr=" << (vec.at(1) = 0) << endl;
        //2. []的直接访问
        cout << "vec: " << vec << endl;
        cout << "vec = 1;-> " << "arr=" << (vec = 1) << endl;
        //3. front()直接获取第一个元素的值
        cout << "vec.front(): " << vec.front() << endl;
        cout << "vec.front() = 1:-> " << (vec.front() = 1) << endl;
        //4. back()直接获取最后一个元素的值
        cout << "vec.back(): " << vec.back() << endl;
        cout << "vec.back() = 1:-> " << (vec.back() = 1) << endl;
        //5. 直接访问内部数组
        int* data = vec.data();
        cout << "data: " << data << endl << endl;

        //获取迭代器 - 一种遍历的手段
        //指向第一个元素的正向
        cout << "遍历向量功能测试: " << endl;
        vector<int, allocator<int>> ::iterator vec_iterator_1 = vec.begin();
        for (int i = 0; i < vec.size(); i++)
        {
                cout << *(vec_iterator_1++) << " ";
        }
        cout << endl;
        //指向逆向的最后一个元素
        vector<int, allocator<int>>::reverse_iterator vec_iterator_2 = vec.rend();
        for (int i = 0; i < vec.size(); i++)
        {
                cout << *(--vec_iterator_2) << " ";
        }
        cout << endl << endl;
        //操作向量所在空间,因为向量具有可变大小,所以包括读取这块空间是否被写入
        //已经使用的空间,当前情况下最大可以使用的空间等基本操作
        //根据大小可变的特性: 还有设置预留空间
        cout << "操作向量所在空间功能测试: " << endl;
        cout << "vec.empty(): " << vec.empty() << endl;
        cout << "vec.size(): " << vec.size() << endl;
        cout << "vec.max_size(): " << vec.max_size() << endl;
        constexpr int max_elements = 32;
        //使用reverse
        {
                cout << "使用reverse: " << endl;
                vector<int, Tools::Vector::my_allocator<int>> temp;
                temp.reserve(max_elements);
                for (int n = 0; n < max_elements; n++)
                {
                        temp.push_back(n);
                }
        }

        //不使用reverse
        {
                cout << "不使用reverse: " << endl;
                vector<int, Tools::Vector::my_allocator<int>> temp;

                for (int n = 0; n < max_elements; n++)
                {
                        if (temp.size() == temp.capacity())
                                std::cout << "size() == capacity() == " << temp.size() << '\n';
                        temp.push_back(n);
                }
        }

}
//-----------------------------------------------------------------------------------//
//main.cpp
#include "Test.h"
int main()
{
        Vector::test();
        return 0;
}
//-----------------------------------------------------------------------------------//



FishC 发表于 2024-12-1 16:10:27

很高兴为你解答!看起来你在使用自定义的分配器 `my_allocator` 时遇到了问题。最可能的原因是你在自定义分配器中调用父类的方法时没有正确地调用它们。

这里有几个小建议来帮助你解决这个问题:

1. **确保子类方法调用父类方法时使用作用域解析运算符**。在 `my_allocator` 中,确保在调用 `std::allocator` 的 `allocate` 和 `deallocate` 方法时使用 `std::allocator<T>::` 进行调用。例如:
   T* allocate(std::size_t n)
   {
       T* p = std::allocator<T>::allocate(n);
       std::cout << "Using custom allocator" << std::endl;
       return p;
   }

2. **检查掉父类方法是否完整地被隐藏**。虽然子类中定义了与父类方法同名的方法,但你也需要明确地调用子类的方法而不是无意中调用了父类的方法。因此,检查你的 `vector` 实例是否明确使用了自定义的 `my_allocator` 而不是默认的 `std::allocator`。

3. **确保模板类定义正确**。你的模板类应确保正确继承并实现所有必要的方法,以下是一个完整的定义:
   template<class T>
   class my_allocator : public std::allocator<T>
   {
   public:
       typedef T value_type;

       my_allocator() = default;
       my_allocator(const my_allocator&) = default;
       ~my_allocator() = default;

       T* allocate(std::size_t n)
       {
         std::cout << "Allocating " << n << " elements." << std::endl;
         return std::allocator<T>::allocate(n);
       }

       void deallocate(T* p, std::size_t n)
       {
         std::cout << "Deallocating " << n << " elements." << std::endl;
         std::allocator<T>::deallocate(p, n);
       }
   };

通过上述检查和调整,应该能正确地让 `vector` 使用你的 `my_allocator` 中的方法。如果问题仍然存在,确保你的 `vector` 创建代码明确指定了这个自定义分配器,例如:
std::vector<int, my_allocator<int>> my_vector;

如果按照这些步骤操作后仍有问题,可能需要检查具体的使用场景和编译器选项来找到更多线索。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 隐藏父类方法出现的问题