0

我在主函数中构建了一些类。因为它们是在局部变量中定义的,所以它们在主返回之后都被解构。但是,我注意到我想避免的奇怪事件。如果我更改其中一个类的内存布局(通过添加或更改字段),然后在链接之前仅重新编译修改后的类,我会得到分段错误或无效指针(取决于我对程序所做的更改) . 如果我也重新编译主文件,则没有错误。

我相当肯定会发生这种情况,因为当我在我的主文件中包含头文件时,它假定为每个类分配一定数量的内存,但是自从 main.o 编译后这个值已经改变,因此它是寻找在程序关闭时解构对象时不存在的内存。

虽然目前重新编译主文件不是问题,但我担心随着项目的增长,我会在其他文件中遇到这个问题,并且每次都重新编译它们以避免错误是不可取的。有没有一种简单的方法可以避免这些错误?

4

4 回答 4

1

某些类成员(例如构造函数和/或析构函数)被内联而有些没有被内联的可能性要大得多,并且每个集合将使用与对象指针不同的偏移量来查找特定成员。

考虑使用类似mkdep生成具有适当源到头依赖关系的 makefile 之类的东西,这样更改头会导致包括该头在内的所有文件被重新编译。

或者,您可以选择在类的源文件中保留所有类成员定义(包括构造函数、复制构造函数和赋值运算符——在这种情况下不应自动生成任何内容),从而有效地禁止内联。在大多数情况下,这应该足以防止这个问题,但它会带来(轻微的)性能成本。(如果您将数据成员添加到类中,这将无济于事 - 从而增加对象的大小 - 除非您另外使用pimpl idiom,它为所有数据成员访问添加了一个间接级别。)

于 2013-03-21T19:16:32.610 回答
1

不可以。如果你的类的布局发生变化,你需要重新编译任何使用该类的单元。

于 2013-03-21T19:16:40.887 回答
0

在阅读了 cdhowie 的回答后,我开始研究 mkdep,但似乎此类程序已被弃用,并且已被执行相同操作的编译器标志所取代。我已经包含了我的 makefile 的主体,它编译了主程序(srcpath 中的代码)和测试(testpath 中的代码)然后运行测试。在此期间创建了两个单独的依赖文件,一个用于 main,另一个用于测试。

src = $(shell cd $(srcpath); find ./ -name "*.cpp")
testsrc = $(shell cd $(testpath); find ./ -name "*.cpp")
obj = $(src:%.cpp=%.o)
testobj = $(testsrc:%.cpp=%.o)
head = $(shell cd $(srcpath); find ./ -name "*.h")
testhead = $(shell cd $(testpath); find ./ -name "*.h")
skip_files = ./main.o

makedep = $(shell $(cpp) $(cflags) -MM -MT '$(patsubst $(srcpath)%.cpp, $(objpath)%.o, $(file))' $(file) >> .depend)
makedeptest = $(shell $(cpp) $(cflags) -MM -MT '$(patsubst $(testpath)%.cpp, $(testobjpath)%.o, $(file))' $(file) >> .dependtest)

all: main Test

Test: .dependtest $(addprefix $(testobjpath),$(testobj))
    @echo "Linking Tests"
    @$(cpp) $(lflags) -o $(testbin) $(addprefix $(testobjpath), $(testobj)) $(addprefix $(objpath), $(filter-out $(skip_files),$(obj)))
    @./$(testbin)

.dependtest: $(addprefix $(testpath), $(testsrc)) $(addprefix $(testpath), $(testhead))
    $(shell rm -f .dependtest)
    $(foreach file,$(addprefix $(testpath), $(testsrc)), $(makedeptest))

$(addprefix $(testobjpath), %.o): $(addprefix $(testpath), %.cpp)
    $(cpp) $(cflags) -c -o $@ $<

main: .depend $(addprefix $(objpath), $(obj))
    @echo "Linking Program"
    @$(cpp) $(lflags) -o $(bin) $(addprefix $(objpath),$(obj))

.depend: $(addprefix $(srcpath), $(src)) $(addprefix $(srcpath), $(head))
    $(shell rm -f .depend)
    $(foreach file, $(addprefix $(srcpath), $(src)), $(makedep))

$(addprefix $(objpath), %.o): $(addprefix $(srcpath), %.cpp)
    $(cpp) $(cflags) -c -o $@ $<

clean:
    -rm $(testbin) $(bin) $(addprefix $(objpath),$(obj)) $(addprefix $(testobjpath),$(testobj))

-include .depend
-include .dependtest
于 2013-03-22T14:51:26.477 回答
-3

使用 IDE 而不是在命令行编译。

于 2013-03-21T19:15:57.647 回答