【问题标题】:Dependency injection with same class name in source links to same object?在指向同一对象的源链接中具有相同类名的依赖注入?
【发布时间】:2021-12-25 13:20:27
【问题描述】:

我可能遗漏了一些基本的东西,但不确定要查找什么来找出什么。

我有一个希望返回的简单程序:

ImplA
ImplB

它实际上返回:

ImplA
ImplA

我知道在每个文件中重命名类“Do”,或者将类定义包装在命名空间中,可以解决这个问题,但是有没有办法让这两个文件的实现名称相同?是否有某种方法可以限制类对文件的可见性?

// main.cpp
#include "do_a.h"
#include "do_b.h"

#include <cstdint>

int32_t main(int32_t,char**) {
    IDo* a = getImplA();
    IDo* b = getImplB();
    
    a->print();
    b->print();

    delete b;
    delete a;

    return 0;
}
// i_do.h
// interface file for DI
#pragma once

class IDo {
public:
    virtual ~IDo() {}
    virtual void print() = 0;
};
// do_a.h
#pragma once
#include "i_do.h"

IDo *getImplA();
// do_b.h
#pragma once
#include "i_do.h"

IDo *getImplB();
// do_a.cpp
#include "do_a.h"
  
#include <iostream>

namespace { // adding anon-namespace seems to be another alternative

class Do : public IDo {
public:
    virtual void print() override {
        std::cout << "ImplA" << std::endl;
    }
};

} 

IDo* getImplA() {
    return new Do();
}
// do_b.cpp
#include "do_b.h"
  
#include <iostream>

namespace {

class Do : public IDo {
public:
    virtual void print() override {
        std::cout << "ImplB" << std::endl;
    }
};

}

IDo* getImplB() {
    return new Do();
}
cmake_minimum_required(VERSION 3.12)

# C++ version required
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_CXX_FLAGS
    "-std=gnu++2a -Wall -Wpedantic -Wextra -fexceptions -O0 -g3 ${CMAKE_CXX_FLAGS_DEBUG}"
)

project(main)

set(CMAKE_BUILD_TYPE "Debug")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(Main main)

set(MainSrc
    main.cpp
)

set(ApplSrc
    do_a.cpp
    do_a.h
    do_b.cpp
    do_b.h
    i_do.h
)

add_executable(${Main} ${ApplSrc} ${MainSrc})

编辑以包装类 Do {...};在匿名命名空间中。

【问题讨论】:

    标签: c++ dependency-injection namespaces


    【解决方案1】:

    没办法。

    您在两个文件中都使用 cout 并期望它是同一个对象。那么 Do 类如何是不同的类型呢?

    命名空间,任何命名空间,都会使名称不同,所以当然可以。

    我会把它们命名为 DoA 和 DoB,然后就可以了。

    【讨论】:

    • 我在考虑对象文件有点分开,我有点惊讶没有任何消息表明两个对象文件中存在相同的类对象。我想它只需要它找到的第一个。在我认为它有道理之后,我一直在用不同的方式命名它们,然后剪切并粘贴了一个快速测试,然后猝不及防。
    • 附加说明,我在事后添加了命名空间。最初它只是原始代码,我有一半希望源文件表现得像在匿名命名空间中一样,在全局命名空间中可以看到 cout 之类的东西。
    • @Steven 源文件与头文件没有什么特别之处,因此所有包含文件中的 everything 也将在两个目标文件中。唯一的区别是来自 的内容在任何地方都是相同的,因此该部分可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    相关资源
    最近更新 更多